线性表(亦作顺序表)是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的。线性表的逻辑结构简单,便于实现和操作。因此,线性表这种数据结构在实际应用中是广泛采用的一种数据结构。
1、结构
线性表是一种常用的数据结构,以下介绍线性表及其顺序存储,并对栈和队列及它们的顺序实现给出了详细的设计描述。
在实际应用中,线性表都是以栈、队列、字符串等特殊线性表的形式来使用的。由于这些特殊线性表都具有各自的特性,因此,掌握这些特殊线性表的特性,对于数据运算的可靠性和提高操作效率都是至关重要的。
线性表是一个线性结构,它是一个含有n≥0个结点的有限序列,对于其中的结点,有且仅有一个开始结点没有前驱但有一个后继结点,有且仅有一个终端结点没有后继但有一个前驱结点,其它的结点都有且仅有一个前驱和一个后继结点。一般地,一个线性表可以表示成一个线性序列:k1,k2,…,kn,其中k1是开始结点,kn是终端结点。
是一个数据元素的有序(次序)集。
2、特征
线性结构的基本特征为:
1.集合中必存在唯一的一个“第一元素”;
2.集合中必存在唯一的一个 “最后元素” ;
3.除最后一个元素之外,均有 唯一的后继(后件);
4.除第一个元素之外,均有 唯一的前驱(前件)。
3、实现
线性表的存储方式与数组类似,都是采用顺序存储的方式。
优点:随机访问元素和查找元素方便、快捷
缺点:删除和插入元素比较慢,要移动大量的元素
C++代码实现:
头文件 SeqList.h
#ifndef _SEQLIST_H
#define _SEQLIST_H
#include<iostream>
using namespace std;
#define ElemType int
#define ELEM_INIT_SIZE 8
#define INC_SIZE 3
typedef struct SeqList
{
ElemType *elem;
size_t capacity;
size_t size;
}SeqList;
//////////////////////////////////////
//////////////////////////////////////
void InitSeqList(SeqList *list);
void push_back(SeqList *list, ElemType x);
void push_front(SeqList *list, ElemType x);
void show_list(SeqList *list);
int Find(SeqList *list, ElemType key);
void delete_val(SeqList *list,ElemType key);
int length(SeqList *list);
void pop_back(SeqList *list);
void pop_front(SeqList *list);
void clear_list(SeqList *list);
void destroy_list(SeqList *list);
void delete_pos(SeqList *list,int pos);
void reverse(SeqList *list);
#endif
函数实现 SeqList.cpp
#include"SeqList.h"
#include<assert.h>
bool IsFull(SeqList *list)
{
return list->size >= list->capacity;
}
bool IsEmpty(SeqList *list)
{
return list->size==0;
}
bool Inc(SeqList *list)
{
list->capacity += INC_SIZE;
list->elem = (ElemType *)realloc(list->elem,sizeof(ElemType)*list->capacity);
if(list->elem == NULL)
{
list->capacity -= INC_SIZE;
return false;
}
return true;
}
void InitSeqList(SeqList *list)
{
list->elem = (ElemType *)malloc(sizeof(ElemType)*ELEM_INIT_SIZE);
assert(list->elem != NULL);
list->capacity = ELEM_INIT_SIZE;
list->size = 0;
}
void push_back(SeqList *list, ElemType x)
{
if(IsFull(list) && !Inc(list))
{
cout<<"空间已满,不能插入元素!"<<endl;
return;
}
list->elem[list->size++] = x;
}
void push_front(SeqList *list, ElemType x)
{
if(IsFull(list))
{
cout<<"空间已满,不能插入元素!"<<endl;
return;
}
for(int i=list->size; i>0; --i)
{
list->elem[i] = list->elem[i-1];
}
list->elem[0] = x;
list->size++;
}
/*
void push_back(SeqList *list, ElemType x)
{
if(list->size >= list->capacity)
{
cout<<"空间已满,不能插入元素!"<<endl;
return;
}
list->elem[list->size++] = x;
}*/
void show_list(SeqList *list)
{
for(int i=0; i<list->size; ++i)
{
cout<<list->elem[i]<<" ";
}
cout<<endl;
}
int Find(SeqList *list, ElemType key)
{
for(int i=0; i<list->size; ++i)
{
if(key == list->elem[i])
return i;
}
return -1;
}
void delete_val(SeqList *list,ElemType key)
{
int pos = Find(list,key);
if(pos != -1)
{
delete_pos(list,pos);
}
else
{
cout<<"要删除的元素不存在!"<<endl;
}
}
int length(SeqList *list)
{
return list->size;
}
void pop_back(SeqList *list)
{
if(IsEmpty(list))
{
cout<<"空间已空,不能插删除元素!"<<endl;
return;
}
list->size--;
}
void pop_front(SeqList *list)
{
if(IsEmpty(list))
{
cout<<"空间已空,不能插删除元素!"<<endl;
return;
}
for(int i=0; i<list->size-1; ++i)
{
list->elem[i] = list->elem[i+1];
}
list->size--;
}
void clear_list(SeqList *list)
{
list->size = 0;
}
void destroy_list(SeqList *list)
{
free(list->elem);
list->elem = NULL;
list->capacity = 0;
list->size = 0;
}
void delete_pos(SeqList *list,int pos)
{
if(IsEmpty(list))
{
cout<<"空间已空,不能插删除元素!"<<endl;
return;
}
if(pos<0 || pos>=list->size)
{
cout<<"位置非法,不能删除!"<<endl;
return;
}
for(int i=pos;i<list->size-1; ++i)
{
list->elem[i] = list->elem[i+1];
}
list->size--;
}
void Swap(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
void reverse(SeqList *list)
{
int head = 0;
int tail = list->size-1;
while(head < tail)
{
//int temp = list->elem[head];
//list->elem[head] = list->elem[tail];
//list->elem[tail] = temp;
Swap(&list->elem[head],&list->elem[tail]);
head++;
tail--;
}
}
测试主函数 Main.cpp
#include"SeqList.h"
void main()
{
SeqList mylist;
InitSeqList(&mylist);
int pos;
ElemType Item;
int select = 1;
while(select)
{
cout<<"*********************************"<<endl;
cout<<"*[1] push_back [2] push_front *"<<endl;
cout<<"*[3] show_list [0] quit_system*"<<endl;
cout<<"*[4] pop_back [5] pop_front *"<<endl;
cout<<"*[6] delete_pos [7] delete_val *"<<endl;
cout<<"*[8] insert_pos [9] insert_val *"<<endl;
cout<<"*[10] find [11]updata_pos *"<<endl;
cout<<"*[12] sort [13]reverse *"<<endl;
cout<<"*[14] length [15]clear_list *"<<endl;
cout<<"*[16] destroy [17]remove_all *"<<endl;
cout<<"*********************************"<<endl;
cout<<"请选择:>";
cin>>select;
switch(select)
{
case 1:
cout<<"请输入要插入的数据(-1结束):>";
while(cin>>Item,Item!=-1)
{
push_back(&mylist,Item);
}
break;
case 2:
cout<<"请输入要插入的数据(-1结束):>";
while(cin>>Item,Item!=-1)
{
push_front(&mylist,Item);
}
break;
case 3:
show_list(&mylist);
break;
case 4:
pop_back(&mylist);
break;
case 5:
pop_front(&mylist);
break;
case 6:
cout<<"请输入要删除的位置:>";
cin>>pos;
delete_pos(&mylist,pos);
break;
case 7:
cout<<"请输入要删除的值:>";
cin>>Item;
delete_val(&mylist,Item);
break;
case 10:
cout<<"请输入要查找的值:>";
cin>>Item;
pos = Find(&mylist,Item)+1;
if(pos==0)
{
cout<<"要查找的元素不存在!"<<endl;
}
else
{
cout<<"pos = "<<pos<<endl;
}
break;
case 13:
reverse(&mylist);
break;
case 14:
break;
default:
break;
}
}
}