2.10.循环链表

十念  金牌会员 | 2024-12-14 23:34:58 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 828|帖子 828|积分 2484



一.循环单链表:

1.图示:


2.代码阐明:




  • 初始化循环单链表时头结点的next指针必须指向头结点
  • 判断循环单链表是否为空只需要判断头结点的next指针是否指向头结点?是:循环单链表为空;否:循环单链表不为空
  • 判断某个结点是否为循环单链表的表尾结点,只需要判断该结点的next指针是否指向该循环单链表的头结点即可
  • 如果循环单链表不为空的话,就需要把表尾结点的next指针指向头结点
3.代码演示:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. typedef struct LNode
  4. {
  5.     int data; //这个数据的类型不是固定的
  6.     struct LNode *next;
  7. }LNode,*LinkList;
  8. //初始化一个循环单链表
  9. bool InitList(LinkList &L) //函数的结果和函数体的结果最终都要用,所以加&
  10. {
  11.     L = (LNode *)malloc( sizeof(LNode) ); //分配一个头结点
  12.     if(L==NULL)
  13.     {
  14.         return false; //内存不足,分配失败
  15.     }
  16.     L->next = L; //头结点的next指针必须指向L即头结点指向头结点(L代表头结点)
  17.     return true;
  18. }
  19. //判断循环单链表是否为空
  20. bool Empty(LinkList L)
  21. {
  22.     if(L->next = L) return true; //头结点指向头结点说明为空
  23.     else return false;
  24. }
  25. //判断结点p是否为循环单链表的表尾结点
  26. bool isTail(LinkList L,LNode *p)
  27. {
  28.     //L代表头结点
  29.     if(p->next = L) //p结点的next指针指回头结点就说明p为表尾结点
  30.     {
  31.         return true;
  32.     }
  33.     else
  34.     {
  35.         return false;
  36.     }
  37. }
  38. int main()
  39. {
  40.     return 0;
  41. }
复制代码
4.循环单链表与非循环单链表的对比:


5.基础操作:


循环单链表和非循环单链表找到尾结点的时间复杂度都是O(n),因为要重新循环遍历到尾;
循环单链表从尾部找到头部的时间复杂度为O(1),因为尾部下一个就是头部->如果经常操作表头和表尾的话,可以让循环单链表的指针指向表尾结点,此时如果在表尾插入或删除结点时大概需要修改该指针;

二.循环双链表:

1.图示:


2.代码阐明:


3.代码演示:

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. typedef struct DNode
  4. {
  5.     int data;
  6.     struct DNode *prior,*next; //*prior为前驱指针,*next为后继指针
  7. }DNode,*DLinklist;
  8. //初始化空的循环单链表
  9. bool InitDLinkList(DLinklist &L)
  10. {
  11.     L = (DNode *)malloc( sizeof(DNode) ); //分配一个头结点
  12.     if(L==NULL) return false; //内存不足,分配失败
  13.     L->prior = L; //头结点的前驱指针prior指向头结点
  14.     L->next = L; //头结点的后继指针next指向头结点
  15.     return true;
  16. }
  17. //判断循环双链表是否为空
  18. bool Empty(DLinklist L)
  19. {
  20.     if(L->next = L)
  21.     {
  22.         return true; //循环双链表的头结点的next指针指向头结点就说明循环双链表为空
  23.     }
  24.     else
  25.     {
  26.         return false;
  27.     }
  28. }
  29. //判断结点p是否为循环双链表的表尾结点
  30. bool isTail(DLinklist L,DNode *p)
  31. {
  32.     if(p->next == L) //结点p的next指针指向头结点就说明p为尾结点
  33.     {
  34.         return true;
  35.     }
  36.     else
  37.     {
  38.         return false;
  39.     }
  40. }
  41. int main()
  42. {
  43.     return 0;
  44. }
复制代码
4.循环双链表的插入:


5.循环双链表的删除:



三.总结:


1.对于平凡带头结点的双链表而言,只有头结点时,它的后继指针和前驱指针都指向NULL;
2.知道表为空时的状态就可以知道怎样初始化;
3.知道怎样判断某个结点是否是表头/尾结点时,就可以知道怎样前向遍历和后向遍历;
4.注:所有链表都不具有随机访问的特性,因此找某个结点时只能通过循环查找,循环要么停在表头结点,要么停在表尾结点。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

十念

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表