数据结构.线性表(2)——链式表
链表(所有元素不考虑相邻位置,哪有空位就到哪里):使用结点存储数据元素,结点的地址可以连续也可以不连续
链表分为单链表/双链表/循环链表。
单链表中一个节点的组成:数据域+指针域,指针于中存放的是是一个指针,指向下一个节点的地址。
1.获得链表第i个数据的算法思路:
1)声明一个结点p指向链表第一个结点,初始化j从1开始;
2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
3)若到链表末尾p为空,则说明第i个元素不存在;
4)否则查找成功,返回结点p的数据。
2.单链表的插入和删除
插入:
1)声明一个结点p指向链表第一个结点,初始化j从1开始;
2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
3)若到链表末尾p为空,则说明第i个元素不存在;
4)否则查找成功,在系统中生成一个空结点s。
5)将数据元素e赋值给s->data;
6)单链表的插入标准语句s->next=p->next; p->next=s;
7)返回成功。
删除:
1)声明一个结点p指向链表第一个结点,初始化j从1开始;
2)当j<i时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
3)若到链表末尾p为空,则说明第i个元素不存在;
4)否则查找成功,将欲删除的结点p->next赋值给q;
5)单链表的删除标准语句p->next=q->next;
6)将q结点中的数据赋值给e,作为返回;
7)释放q结点;
8)返回成功。
3.单链表整表创建的算法思路:
1)声明一结点p和计数器变量i
2)初始化一空链表L;
3)让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
4)循环:
- 生成一新结点赋值给p;
- 随机生成一数字赋值给p的数据域p->data;
- 将p插入到头结点与前一新结点之间。
1 ///Name:LinkList 2 ///Author:JA 3 ///Date:2015-3-1 4 5 6 7 ///线性表的单链式存储结构 8 #include<stdio.h> 9 #include<stdlib.h> 10 #include<malloc.h> 11 12 typedef struct LNode{ 13 ElemType data; 14 struct LNode * next; 15 }LNode, *LinkList; 16 17 typedef int ElemType; 18 typedef int Status; 19 20 Status GetElem_L(LinkList *L,int i,ElemType &e){ 21 //L为带头结点的单链表的头指针 22 //当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR 23 p = (*L)->next; j = 1; //初始化,p指向第一个结点,j为计数器 24 while (p && j < i){ 25 p = p->next; ++j; 26 } 27 if (!p || j>i) return ERROR; 28 e = p->data; 29 return OK; 30 }//GetElem_L 31 32 //逆位序输入n个元素的值,建立带表头结点的单链线性表L 33 void CreatList_L(LinkList *L, int n){ 34 L = (LinkList)malloc(sizeof(LNode)); //先建立一个带头结点的单链表 35 L->next = NULL; 36 for (i = n; i > 0; --i){ 37 p = (LinkList)malloc(sizeof(LNode)); //生成新结点 38 scanf(&p->data); //输入元素值 39 p->next = L->next; L->next = p; //插入到表头 40 } 41 }//CreatList_L 42 43 44 45 ///在表L中删除第i个元素,并用e返回其值 46 Status ListDelete_L(LinkList *L, int i, ElemType *e){ 47 p = L; j = 0; 48 while (p->next&&j < i - 1){ //寻找第i个结点,并令p指向其前驱 49 p = p->next; ++j; 50 } 51 if (!(p->next) || j>i - 1) return ERROR; 52 q = p->next; p->next = q->next; //删除并释放结点 53 e = q->data, free(q); 54 return OK; 55 }//ListDelete_L