《数据结构》进行曲--带头结点的单循环链表的基本操作

前端之家收集整理的这篇文章主要介绍了《数据结构》进行曲--带头结点的单循环链表的基本操作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

单循环链表

循环链表的特点是最后一个元素的指针域指向头结点。



因此对于循环链表的初始化(设表的头结点是L, 不再是L->next=NULL,而是L->next=L。循环链表为空时,头结点的下一个结点依然是头结点本身。因此但虚幻链表的初始化如下:(数据类型设为int)

  1. //初始化
  2. int InitList(LinkList &L){
  3. L=new LNode;
  4. L->next=L;//非循环链表的初始化是头指针的指针域置空 L->next=NULL
  5. return 1;
  6. }

所以根据循环链表的特点,判断循环链表是否为空时,只需判断头结点的下一个结点是否是头结点即可:
  1. //判断链表是否为空
  2. int ListEmpty(LinkList L){
  3. if(L->next==L){
  4. return 1;//空
  5. }else{
  6. return 0;//非空
  7. }
  8. }

从头检查每一个结点,若当前结点不是头结点,则链表长度加1,由此可计算链表的长度:

  1. //获取链表长度
  2. int ListLength(LinkList L){
  3. int length=0;
  4. struct LNode *p;
  5. p=L->next;
  6. while(p!=L){//当p不是头结点时,链表长度加1
  7. p=p->next;
  8. ++length;
  9. }
  10. return length;
  11. }

  1. //遍历链表
  2. void TraveList(LinkList L){
  3. struct LNode *p;
  4. p=L->next;
  5. printf("遍历链表:\n");
  6. while(p!=L){//当p不是头结点时,输出元素值
  7. printf("%d ",p->data);
  8. p=p->next;
  9. }
  10. printf("\n");
  11. }

使用头插法和尾插法创建单循环链表的方法和创建一般单链表的操作一样,区别在于建立空链表的语句不同。一般单链表是L->next=NULL,而单循环链表是L->next=L。
  1. //头插法创建单循环链表
  2. void CreateList1(LinkList &L,int n){
  3. //创建长度为n的单循环链表
  4. L=new LNode;
  5. L->next=L;
  6. printf("请输入链表元素值:\n");
  7. for(int i=n;i>0;--i){
  8. printf("请输入第%d个元素的值:",i);
  9. struct LNode *p;
  10. p=new LNode;//生成新结点
  11. scanf("%d",&p->data);
  12. p->next=L->next;;
  13. L->next=p;
  14. }
  15. }

  1. //尾插法创建单循环链表
  2. void CreateList2(LinkList &L,int n){
  3. L=new LNode;
  4. L->next=L;
  5. struct LNode *r;
  6. r=L;
  7. for(int i=0;i<n;i++){
  8. printf("请输入第%d个元素的值:",i+1);
  9. struct LNode *p;
  10. p=new LNode;
  11. scanf("%d",&p->data);
  12. p->next=L;
  13. r->next=p;
  14. r=p;
  15. }
  16. }

单循环链表的删除操作和一般单链表的操作时一样的。要注意的是单循环链表的插入操作:
  1. //单循环链表的删除操作
  2. int ListDelete(LinkList &L,int location,int &e){
  3. //删除L中location位置的元素,并用e返回其值
  4. struct LNode *p;
  5. p=L;
  6. int j=0;
  7. while(p->next!=L&&j<location-1){
  8. p=p->next;
  9. ++j;
  10. }
  11. if(p==L||j>location-1){
  12. return 0;
  13. }
  14. struct LNode *q;
  15. q=new LNode;
  16. q=p->next;
  17. p->next=q->next;
  18. e=q->data;
  19. delete q;
  20. return 1;
  21. }

  1. //单循环链表的插入操作
  2. int ListInsert(LinkList &L,int &e){
  3. //在L的location位置插入元素e
  4. struct LNode *p;
  5. p=L;
  6. int j=0;
  7. while(p->next!=L&&j<location-1){
  8. <span style="color:#ff0000;">//注意:由于p初始时指向头结点,所以循环的条件是 p->next!=L
  9. //而不是 p!=L
  10. p=p->next;
  11. ++j;
  12. }
  13. if(p==L||j>location-1){
  14. return 0;
  15. }
  16. struct LNode *s;
  17. s=new LNode;
  18. s->data=e;
  19. s->next=p->next;
  20. p->next=s;
  21. return 1;
  22. }

单循环链表的基本操作的实现:
  1. #include<stdio.h>
  2. #include<iostream>
  3. using namespace std;
  4.  
  5. #define MAX 100
  6.  
  7. //存储结构
  8. typedef struct LNode{
  9. int data;
  10. struct LNode *next;
  11. }LNode,*LinkList;
  12.  
  13. //初始化
  14. int InitList(LinkList &L){
  15. L=new LNode;
  16. L->next=L;//非循环链表的初始化是头指针的指针域置空 L->next=NULL
  17. return 1;
  18. }
  19.  
  20. //判断链表是否为空
  21. int ListEmpty(LinkList L){
  22. if(L->next==L){
  23. return 1;//空
  24. }else{
  25. return 0;//非空
  26. }
  27. }
  28.  
  29. //获取链表长度
  30. int ListLength(LinkList L){
  31. int length=0;
  32. struct LNode *p;
  33. p=L->next;
  34. while(p!=L){//当p不是头结点时,链表长度加1
  35. p=p->next;
  36. ++length;
  37. }
  38. return length;
  39. }
  40.  
  41. //遍历链表
  42. void TraveList(LinkList L){
  43. struct LNode *p;
  44. p=L->next;
  45. printf("遍历链表:\n");
  46. while(p!=L){//当p不是头结点时,输出元素值
  47. printf("%d ",p->data);
  48. p=p->next;
  49. }
  50. printf("\n");
  51. }
  52.  
  53. //头插法创建单循环链表
  54. void CreateList1(LinkList &L,&p->data);
  55. p->next=L->next;;
  56. L->next=p;
  57. }
  58. }
  59.  
  60. //尾插法创建单循环链表
  61. void CreateList2(LinkList &L,&p->data);
  62. p->next=L;
  63. r->next=p;
  64. r=p;
  65. }
  66. }
  67.  
  68. //单循环链表的插入操作
  69. int ListInsert(LinkList &L,int &e){
  70. //在L的location位置插入元素e
  71. struct LNode *p;
  72. p=L;
  73. int j=0;
  74. while(p->next!=L&&j<location-1){
  75. //注意:由于p初始时指向头结点,所以训话的条件是 p->next!=L
  76. //而不是 p!=L
  77. p=p->next;
  78. ++j;
  79. }
  80. if(p==L||j>location-1){
  81. return 0;
  82. }
  83. struct LNode *s;
  84. s=new LNode;
  85. s->data=e;
  86. s->next=p->next;
  87. p->next=s;
  88. return 1;
  89. }
  90.  
  91. //单循环链表的删除操作
  92. int ListDelete(LinkList &L,并用e返回其值
  93. struct LNode *p;
  94. p=L;
  95. int j=0;
  96. while(p->next!=L&&j<location-1){
  97. p=p->next;
  98. ++j;
  99. }
  100. if(p==L||j>location-1){
  101. return 0;
  102. }
  103. struct LNode *q;
  104. q=new LNode;
  105. q=p->next;
  106. p->next=q->next;
  107. e=q->data;
  108. delete q;
  109. return 1;
  110. }
  111. int main(){
  112. LinkList L;
  113. if(InitList(L)){
  114. printf("初始化成功!\n");
  115. }else{
  116. printf("初始化失败!\n");
  117. }
  118. if(ListEmpty(L)){
  119. printf("当前链表为空.\n");
  120. }else{
  121. printf("链表非空.\n");
  122. }
  123. printf("请输入链表长度:");
  124. int n;
  125. scanf("%d",&n);
  126. //CreateList1(L,n);
  127. CreateList2(L,n);
  128. if(ListEmpty(L)){
  129. printf("当前链表为空.\n");
  130. }else{
  131. printf("链表非空.\n");
  132. }
  133. printf("当前链表长度是:%d\n",ListLength(L));
  134. TraveList(L);
  135. printf("请输入插入位置和值:\n");
  136. int location,e;
  137. scanf("%d%d",&location,&e);
  138. if(ListInsert(L,location,e)){
  139. printf("插入成功\n");
  140. }else{
  141. printf("插入失败\n");
  142. }
  143. TraveList(L);
  144. printf("请输入删除元素的位置:\n");
  145. int e1,location1;
  146. scanf("%d",&location1);
  147. if(ListDelete(L,location1,e1)){
  148. printf("删除成功\n");
  149. printf("删除的元素值为:%d\n",e1);
  150. }else{
  151. printf("删除失败\n");
  152. }
  153. TraveList(L);
  154. }



错误敬请读者指出。

猜你在找的数据结构相关文章