线性表
1.线性表(List):零个或多个数据元素的有限序列。
2.线性表元素的个数n定义为线性表的长度,当n=0时,称为空表。
3.在较复杂的线性表中,一个数据元素可以由若干个数据项组成。
顺序储存
**1.如何实现:**一维数组来实现顺序储存结构。
2.数组长度与线性表长度的区别:
数组长度是存放线性表的储存空间的长度,储存分配后这个量一般是不变的。
线性表长度是线性表中数据元素的个数,随着线性表插入和删除操作的进行,这个量会发生变化。
在任意时刻,线性表长度应当小于数组长度。
3.插入操作
思路:
1)位置不合理,返回异常
2)若线性表长度超出数组长度,返回异常或者增加容量(这样说顺序储存的一个缺点所在)
3)从最后一个元素开始一直遍历到第i个位置,分别将后面的元素后移一位
4)将插入元素放入到第i个位置
5)表长+1
4.删除操作
思路:
1)若删除位置不合理,返回异常
2)取出删除元素
3)从删除位置开始遍历到最后一个元素位置,分别将他们都向前移一个位置
4)表长-1
链式储存
链式储存又分为单链表,静态链表,循环列表,双向链表,单链表的增删改查在这里就不多说了,以下介绍另外几种。
静态链表
1.定义:用数组描述链表:让数组的每个元素都是由两个数据域组成,data和cur,data储存我们通常需要处理的元素,cur储存该元素后继在数组中的下标,相当于单链表中的next指针。
2.静态链表初始化
代码实现:
#define OK 1
struct space
{
int data;
int cur;
};
//maxsize 为链表长度,最后一个链表cur为0,表示无指向
status initlist(staticlist space)
{
int i;
for(i=0;i<maxsize-1;i++)
space[i].cur=i+1;
space[maxsize-1].cur=0;
return OK;
}
3.静态链表的插入
代码实现:
#define OK 1
#define ERRROR 0
struct space
{
int data;
int cur;
};
//如果链表非空,则返回结点下标
int Malloc_SLL(staticlist space)
{
int i=space[0].cur;//返回第一个备用的空闲空间
if(space[0].cur)
{
space[0].cur=space[i].cur;
}
return i;
}
status listinsert(statuslist L,int i,eletype e)
{
int k,j,l;
k=maxsize-1;//k是最后一个元素的下标
//数据溢出,添加失败
if(i<1||i>listlength(L)+1)
return ERROR;
j=Malloc_SLL(L);//获得空闲分量的下标
if(j)
{
L[j].data=e;//将数据赋值
for(l=1;l<=i-1;l++)
k=L[k].cur;
L[j].cur=L[k].cur;//把i元素之前的cur赋值给新元素的cur
L[k].cur=j;//把新元素的cur赋值给i元素之前的cur
return OK;
}
return ERROR;
}
4.静态链表的删除
代码实现:
//删除L中第i个元素e
status listdelete(staticlist L,int i)
{
int j,k;
if(i<1||i>listlength(L)-1)
return ERROR;
k=maxsize-1;
for(j=1;j<i-1;j++)
k=L[k].cur;
j=L[k].cur;
L[k].cur=L[j].cur;
return OK;
}
循环链表
1.定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环列表。
2.原来单链表是判断p->next是否为空,现在是判断p->next不等于头结点。
3.为了使得查找尾结点的时间复杂度为O(1),我们引用了尾结点,应用:将两个循环链表合并成一个表。
代码:
p=rearA->next;//保存A的头结点
rearA->next=rearB->next->next;//将B的第一个结点赋值给A的头结点
q=rearB->next;
rearB->next=p;//将A原来的头结点给rearB->next
free(p);
双向链表
1.定义:双向链表是在单链表的每个结点中,在设置一个指向其前驱结点的指针域。
struct Dulnode
{
elemtype data;//数据域
struct Dulnode *prior;
struct Dulnode *next;
};
2.插入
//将s插入到结点p和p->next之间
s->prior=p;
s->next=p->next;
p->next->prior=s;
p->next=s;
3.删除
//删除结点p
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);