数据结构:线性表
线性表的定义
线性表(List):零个或多个数据元素的有限序列.
除了第一个元素每一个元素都有一个后继,除了第一个元素每个元素都有一个前驱。
相同的逻辑结构但是线性表可以由不同的物理结构形成
1.顺序存储结构
//在存储空间上采用顺序存储的方法进行存储
#define MAXSIZE 20
typedef int ElemType;
typedef struct
{
int lenth;//用于表示线性表的当前长度
ElemType data[MAXSIZE];//用于储存元素的数组,最大的存储量为MAMXSIZE
}SqList;
注意:数组长度和线性表的长度是两个概念,数组的长度是存放线性表空间的长度,在声明分配空间后这个空间的大小是不会轻易改变的,一些高级语言虽然可以动态分配数组的空间,但是这会损耗程序的一些性能。线性表的长度是线性表中元素的个数,这个量一直都在变化
//顺序存储的线性表的各种基本函数的实现
void InitList(SqList *L)//创建一个线性表
{
int len;//线性表的长度
cout<<"请输入线性表的长度";
cin>>len;
while(len>MAXSIZE)
{
cout<<"溢出,请重新输入线性表的长度"<<endl;
cin>>len;
}
L->lenth=len;
//输入链表需要的元素
for(int i=0;i<len;i++)
{
cin>>(*L).data[i];
}
}
//判断线性表是否为空表
bool ListEmpty(SqList L)
{
if(!(l.lenth))
return 1;
else return 0;
}
//将线性表清空
void ClearList(SqList *L)
{
free(L);
}
//将线性表中的第i个位置的元素返回
ElemType GetElem(SqList L,int i)
{
return L.data[i-1];
}
//在第i个位置插入e元素
void ListInsert(SqList *L,int i,int e)
{
if(L->lenth==MAXSIZE)
{
cout<<"线性表已满,插入失败"<<endl;
return ;
}
if(i<1||i>lenth+1)
{
cout<<"没有这样一个位置"<<endl;
return ;
}
for(int j=i;j<lenth+1;j++)
{
(*L).data[j]=(*L).data[j-1];
}
(*L).data[i-1]=e;
}
//将排在第i个位置的元素删除
void ListDelete(SqList *L,int i,ElemType *e)
{
int k;
if(L->lenth==0)
{
cout<<"表已空,删除失败";
return ;
}
if(i<1||i>L->lenth)
{
cout<<"不存在你所要求的位置"<<endl;
return ;
}
*e=L->data[i-1];
if(i<L->lenth)
{
for(k=i;k<L->lenth;k++)
{
L->data[k-1]=L->data[k];
}
}
L->lenth--;
}
//题外话:在使用结构体的函数中我们大多数使用指针作为形参,因为指针的传输比整个结构体的传输效率更高,因此更加有利于提高程序的工作效率
顺序存储的优缺点
- 优点:
+ 无须为元素的逻辑关系而增加占用空间
+ 可以快速地访问其中的任何一个元素 - 缺点
+ 插入和删除需要移动大量的元素
+ 当线性表长度变化较大时不易确定其所需要占用的空间
+ 容易造成存储空间的碎片
2.链式存储
首先来定义节点
typedef struct Node
{
ElemType data;//节点中存储的数据
struct Node *next;//用于指向下一个节点的指针
}Node;
接着我们来定义链表
typedef struct Node *LinkList;//定义LinkList
//链表的初始化
int main()
{
LinkList L=new(sizeof(Node));//声明头节点
int len;
cout<<"请输入您期待的线性表长度"<<endl;
cin>>len;
Linklist p