线性表的链式存储结构
链式存储结构分为:单链表,静态链表,循环链表,双向链表。
单链表:对数据元素ai来说,除了存储其本身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。n个结点(ai的存储映像)链结成一个链表,即为线性表 (a1,a2,a3.....an)的链式存储结构,因为此链表的每一个结点中只包含一个指针域,所以叫做单链表。
链表的第一个结点的存储位置叫做头指针。
为了更方便地对链表进行操作,会在单链表的第一个结点前附设一个结点,称为头结点。
头指针与头结点的异同:
头指针:
1、头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针。
2、头指针具有标识作用,所以常用头指针冠以链表的名字。
3、无论链表是否为空,头指针均不为空。头指针是链表的必要元素。
头结点:
1、头结点是为了操作的统一和方便而设立的,放在第一元素的结点之前,其数据域一般无意义(也可以存放链表的长度)。
2、有了头结点,对在第一元素结点前插入结点和删除第一结点,其操作与其他结点的操作就统一了。
3、头结点不一定是链表的必要元素。
结点由存放数据元素的数据域和存放后继结点地址的指针域组成。
如果p->data=ai,那么p->next->data=a(i+1)。
单链表的读取:单链表的读取方法是从头开始找。因此,时间复杂度是O(n)。
单链表的插入和删除
插入操作:假设结点s要插入到结点p、p->next之间。
s->next=p->next;
p->next=s;
在第 i 个数据的位置插入结点的思路:
1、查找第 i 个的位置,若到链表尾为空,则第 i 个元素不存在,否则查找成功。
2、在系统中生成一个空结点 s。
3、将数据元素 e赋值给s->data。
4、s->next=p->next;p->next=s;
5、返回成功。
删除操作:设存储元素ai的结点是q,要实现结点q删除单链表的操作,其实就是绕过结点q。
q=p->next;
p->next=q->next;
在第 i 个数据的位置插入结点的思路:
1、查找第 i 个的位置,若到链表尾为空,则第 i 个元素不存在,否则查找成功。
2、将欲删除的结点p->next赋值给q。
3、p->next=q->next。
4、将q结点中的数据赋值给e,作为返回,释放q。
单链表的整表创建
代码算法大致如下:
Linklist p;
int i;
*L=(Linklist)malloc(sizeof(Node));
(*L)->next=NULL;
for(i=0;i<n;i++)
{
p=(Linklist)malloc(sizeof(Node));
p->data=rand()%100+1;
p->next=(*L)->next;
}