本章有三个大的知识点:线性表的定义;顺序表;链表
1.线性表
定义:具有相同数据类型的n各数据元素的有限序列。且每个元素(除第一个元素)都仅有唯一前驱,每个元素(除最后一个)每个元素仅有一个后继。线性表是逻辑结构
大白话就是:线性表,不要把他看作表,而是把他看作一条直线,直线上有n个点(每个点相当于元素,点与点之间的线段相当于数据元素之间的关系)。每个点只与前一个元素和后一个元素有联系。
之前也说了,数据结构,除了数据,关系,还有数据操作。由于不同的存储结构会出现不同的操作,具体的代码会在相应的知识点中补充,这里只写出相关操作(可以跳过)。
InitList(&L); 构建一个表
Length(L); 求表长
LocateElem(L,e); 查找表中值为e的元素位置
GetElem(L,e); 查找位置为e的元素的值
ListInsert(&L,i,e); 在位置i插入元素e
ListDelete(&L,i&e); 删除元素e
PrintfList(L); 打印表
DestroyList(&L); 销毁表
2.顺序表
顺序表为线性表的顺序存储结构,在内存中连续存储,逻辑上相邻的两个元素在物理位置上也相邻
如何建立一个顺序表呢?答案很简单,直接建立一个数组就可以了
InitList(L)
{
typename a[L];//typename代表任何数据类型,比如int,char,float等
rerurn a;//返回表的地址
}
由上面的代码可以看出线性表的构建是需要提前知道表的长度的,这就限制了顺序表的灵活性,你必须提前知道表长才能构建,否则在c语言中是无法构建成功的。
以下给出几个顺序表的重要代码
插入操作,在顺序表的第i个位置插入新元素e
bool ListInsert(int *q ,int i,int e,int L)
{
int j;
if(L>=Maxsize)//判断表是否已满
printf("表已满"),return false;
if(i>L+1||i<1)//判断插入位置是否错误
printf("插入位置错误"),return false;
for(j=L;j>=i;j--)
*(p+j)=*(p+j-1);
*(p+i-1)=e;
return true;
}
由上面的代码可知,顺序表的插入平均时间复杂度为O(n)(最好为1,最坏为n),因为要移动插入后的元素
删除表中的第i位置的元素
bool DelList(int *p,int i,int *L)//删除后需要修改L的值,所以这里传递的是L的地址
{
int j;
if(i>*L+1||i<1)
printf("删除位置错误"),return false;
else
{
for(j=i-1;j<*L-1;j++)
*(p+j)=*(p+j+1);
}
*L=*L-1;
return true;
}
3.链表
链表采用的方式是,给每个元素分两个区域,一个用来存值,一个用来存下一个元素的地址,这里就要用到结构体了。
定义如下:
struct LinkList
{
int data;
struct LinkList *next;
}Lnode;
出现链表的原因是,如果数据量过大那系统是没有办法给予足够大的连续的内存空间来存储这么多数据,而链表不需要连续的空间,只需要总量足够就行了。
一般的,我们会把第一个节点的数据设置为空,指针指向第二个节点,把第一个节叫做头指针,第二个节点存储第一个数据。