【数据结构——线性表之链表】

- 日理万妓 2022-12-11 07:59 510阅读 0赞

【数据结构——线性表之链表】

目录

  • 【数据结构——线性表之链表】
  • 一、单链表
    • (一)单链表的描述
    • (一)单链表的操作实现
      • 1、初始化
      • 2、查找
      • 3、插入
      • 4、删除
      • 5、单链表的建立(前插法)
      • 6、单链表的建立(后插法)
  • 二、循环链表
  • 三、双向链表
      • 1、插入
      • 1、删除

一、单链表

(一)单链表的描述

  1. typedef struct LNode {
  2. ElemType data;//结点数据域
  3. struct LNode* next;//结点指针域
  4. }LNode ,*LinkList;
  5. 变量定义:
  6. LNode* p, * q LinkList L;
  7. p, q, L都是指针变量,* p, * q, * L都是结点变量
  8. 指针变量p : 表示结点地址
  9. 结点变量* p:表示一个结点
  10. p->data;//表示数据域
  11. p->next;//表示指针域
  12. typedef struct LNode {
  13. ElemType data;//结点数据域
  14. struct LNode* next;//结点指针域
  15. }LNode ,*LinkList;
  16. LinkList p, s, L;//指针变量的定义
  17. L = new LNode;//为指针变量L分配内存空间
  18. p = L;//p指向头结点
  19. s = L->next;//s指向首元结点

(一)单链表的操作实现

1、初始化

算法思想:
(1)、生成新结点作为头结点,用头指针L指向头结点
(2)、头结点的指针域置为空

  1. /*初始化*/
  2. Status InitList(LinkList& L)
  3. {
  4. L = new LNode;//生成新结点作为头结点,用头指针L指向头结点
  5. L->next = NULL;//头结点的指针域置为空
  6. return OK;
  7. }

2、查找

在这里插入图片描述

算法思想:
(1)、初始化,p指向第一个结点,j为计数器
(2)、从链表头依次向后扫描,直到p为空或p指向第i个元素
(3)、更新p指向当前结点,计数器+1
(4)、i 值不合法(i<=0或者i>n)
(5)、取第i个结点的数据域

  1. /*按序号查找*/
  2. Status GetElem(LinkList L, int i, ElemType& e)
  3. {
  4. LinkList p;
  5. int j;
  6. p = L->next;j = 1;//初始化,p指向第一个结点,j为计数器
  7. while (p && j < i)//从链表头依次向后扫描,直到p为空或p指向第i个元素
  8. {
  9. p = p->next;//更新p指向当前结点
  10. ++j;//计数器+1
  11. }
  12. if (!p || j > i) return ERROR;//i 值不合法(i<=0或者i>n)
  13. e = p->data;//取第i个结点的数据域
  14. return OK;
  15. }

3、插入

在这里插入图片描述

算法思想:
(1)找到a i - 1的存储位置p
(2)生成一个新结点 * s
(3)将新结点 * s的数据域置为e
(4)新结点 * s的指针域指向a i
(5)结点p指针域指向结点s

  1. /*插入*/
  2. Status ListInsert(LinkList & L, int i, ElemType e)
  3. {
  4. p = L;
  5. int j = 0;
  6. while (p && j < i - 1)//寻找第i - 1个结点
  7. {
  8. p = p->next;//指向当前结点
  9. ++j;
  10. }
  11. if (!p || j > i - 1) return ERROR;//i值不合法
  12. LinkList s;
  13. s = new LNode;//生成新结点s
  14. s->data = e;//新结点的数据域置为e
  15. s->next = p->next;//新结点 * s的指针域指向a i
  16. p->next = s;//结点*p指针域指向结点*s
  17. return OK;
  18. }

4、删除

在这里插入图片描述

算法思想:
(1)查找结点a i-1所在位置,并由指针p指向该结点
(2)临时保存待删除结点ai的地址在q中,以备释放
(3)将结点*p指向结点ai的直接后继结点
(4)释放结点ai的空间

  1. Status LinkDelete(LinkList & L, int i)
  2. {
  3. p = L;
  4. j = 0;
  5. while (p->next && j < i - 1)//寻找第i-1个结点
  6. {
  7. p = p->next;
  8. ++j;
  9. }
  10. if (!(p->next) || j > i - 1) return ERROR;
  11. q = p->next;//临时保存待删除结点ai的地址在q中,以备释放
  12. p->next = q->next;//将结点*p指向结点ai的直接后继结点
  13. delete q;//释放结点ai的空间
  14. return OK;
  15. }

5、单链表的建立(前插法)

在这里插入图片描述

描述:前插法是通过将新结点逐个插入链表的头部(头结点之后)来创建链表,每次申请一个新结点,读入相应的数据元素值,然后将新结点插入到头结点之后。

算法思想
(1)创建一个只有头结点的空链表。
(2)根据待创建链表包括的元素个数n,循环n次执行以下操作:
1、生成一个新结点p;
2、输入元素值赋值给新结点
p的数据域;
3、将新结点*p插入到头结点之后。

  1. /*单链表的建立(前插法)*/
  2. void CreateList(LinkList& L, int n)
  3. {
  4. L = new LNode;//建立一个带头结点的空链表
  5. L->next = NULL;
  6. for (i = n;i > 0;--i)//循环插入新结点
  7. {
  8. p = new LNode;//生成新结点*p
  9. scanf_s("%d", &p->data);//输入元素赋值给p->data
  10. p->next = L->next;//将新结点*p插入到头结点后
  11. L->next = p;
  12. }
  13. }

6、单链表的建立(后插法)

在这里插入图片描述

描述:后插法是通过将新结点逐个插入到链表的尾部来创建链表。同前插法一样,每次申请一个新结点,读入相应数据元素值。不同的是,为了使新结点能够插入到表尾,需要增加一个尾指针r指向链表的尾结点。

算法思想:
(1)创建一个只有头结点的空链表
(2)尾指针r初始化,指向头结点
(3)根据创建链表包括的元素个数n,循环n次执行以下操作:
1、生成一个新结点p;
2、输入元素值赋给新结点
p的数据域
3、将新结点p插入到尾结点r之后;
4、尾指针r指向新的尾结点*p.

  1. /*单链表的建立(后插法)*/
  2. void CreateList(LinkList& L, int n)
  3. {
  4. L = new LNode;//建立带头结点的空链表
  5. L->next = NULL;
  6. r = L;//尾指针指向头结点
  7. for (i = 0;i < n;i++)
  8. {
  9. p = new LNode;//生成新结点p
  10. scanf_s("%d", &p->data);//输入数据域
  11. p->next = NULL;
  12. r->next = p;//插入到尾表
  13. r = p;//r指向新的尾结点
  14. }
  15. }

二、循环链表

特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。
在这里插入图片描述
从循环链表中的任何一个结点的位置都可以找到其他所有的结点,而单链表做不到,循环链表中没有明显的尾端。

在这里插入图片描述
实现

  1. p->next = B->next;
  2. B->next = A->next;
  3. A->next = p->next;
  4. delete p;
  5. A = B;

三、双向链表

有两个指针域的链表,称为双链表

  1. /*双向链表的存储结构*/
  2. typedef struct DuLNode {
  3. ElemType data;//数据域
  4. struct DuLNode *prior;//前指针域
  5. struct DuLNode* next;//后指针域
  6. }DuLNode,*DuLinkLst;

在这里插入图片描述

1、插入

在这里插入图片描述

  1. /*双向链表的插入*/
  2. Status ListInsert_DuL(DuLinkList& L, int i, ElemType e)
  3. {
  4. if (!(p = GetElemP_DuL(L, i)))//在L中确定第i个元素的位置指针p
  5. retrun ERROR;//p为NULL时,第i个元素不存在
  6. s = new DuLNode;//生成一个新结点s
  7. s->data = e;//将数据e存入到结点s的数据域data中
  8. s->prior = p->prior;//将结点s的前指针指向前一个结点
  9. p->prior->next = s;//将前一个结点的后指针指向新结点s
  10. s->next = p;//新结点s的后指针指向p
  11. p->prior = s;//p的前指针指向新结点
  12. return OK;
  13. }

1、删除

在这里插入图片描述

  1. /*双向链表的删除*/
  2. Status ListDelete_DuL(DuLinkList& L, int i, ElemType &e)
  3. {
  4. if (!(p = GetElemP_DuL(L, i)))//在L中确定第i个元素的位置指针p
  5. retrun ERROR;//p为NULL时,第i个元素不存在
  6. e = p->data;//保存被删除结点的数据域
  7. p->prior->next = p->next;//修改被删除结点的前驱结点的后继指针
  8. p->next->prior = p->prior;//修改被删除结点的后继结点的前驱指针
  9. delete p;//释放被删除结点的空间
  10. return OK;
  11. }

发表评论

表情:
评论列表 (有 0 条评论,510人围观)

还没有评论,来说两句吧...

相关阅读