当前位置:   article > 正文

数据结构----C++ 判断一个带表头结点的双向循环链表L是否对称相等的算法_判断循环双链表是否对称

判断循环双链表是否对称

设计算法,判断带头结点的循环双向链表是否对称

算法思路:
⚫ 建立两个工作指针p和q,p从左向右扫描L,q从右向左扫描L,两者同时扫描
⚫ 进入while循环判断,若p与q不相等且p的后继不等于q
⚫ 若对应数据结点的data域相等,则继续循环,否则退出循环
⚫ 判断最后一次的数据结点的data域是否相等且sym==1

核心代码:

  1. int CirLinkList::symmetry(){
  2. int sym=1;
  3. CirNode *p=first->next, *q=first->prior;
  4. while((p!=q&&q!=p->next) && sym==1){
  5. if (p->data==q->data){
  6. p=p->next;
  7. q=q->prior;
  8. }
  9. else sym=0;
  10. }
  11. if(sym==1 && p->data!=q->data)
  12. sym=0;
  13. return sym;
  14. }

调试代码:

  1. #include <iostream>//引入输入输出流
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. using namespace std; //将循环双链表的结点结构定义,循环双链表类定义和各个成员函数定义写到这里
  5. typedef int DataType;
  6. typedef struct CirNode
  7. {
  8. DataType data;//数据域
  9. struct CirNode * next;//前驱指针域
  10. struct CirNode * prior; //后继指针域
  11. }CirNode;
  12. //循环双链表的实现
  13. class CirLinkList{
  14. public:
  15. CirLinkList();//建立只有头结点的空链表
  16. CirLinkList(DataType a[],int n);//建立n个元素的循环双链表
  17. bool Empty();//判断线性表是否为空
  18. int Length();
  19. void PrintList();//遍历操作,按序号依次输出各元素
  20. void GetNode(int i);//通过数据得到结点
  21. void PrintCirNode(CirNode *node);//遍历操作
  22. void RunPrintCirCirNode();//从任意位置遍历链表
  23. void Print_NearBothNode(int i);//从任意位置查询结点的前驱和后继
  24. void Insert(int i,DataType x);
  25. DataType Delete(int i);
  26. int symmetry();//判断带头结点的循环双向链表是否对称
  27. private:
  28. CirNode *first;//循环双链表的头指针
  29. };
  30. //判断是否为空
  31. bool CirLinkList::Empty()
  32. {
  33. if(first->next == first)
  34. {
  35. return true;
  36. }
  37. else{
  38. return false;
  39. }
  40. }
  41. //求循环双链表的长度
  42. int CirLinkList::Length(){
  43. CirNode *p = first->next;//工作指针初始化
  44. int count = 0;//累加器初始化
  45. while(p!=first)
  46. {
  47. p=p->next;
  48. count++;
  49. }
  50. return count;//注意count的初始化和返回值之间的关系
  51. }
  52. //建立循环双链表 尾插法
  53. CirLinkList::CirLinkList(DataType a[],int n)
  54. {
  55. first = new CirNode();
  56. CirNode *r=first,*s = nullptr;//尾指针初始化
  57. for(int i=0;i<n;i++)
  58. {
  59. s=new CirNode();
  60. s->data=a[i];
  61. r->next=s;
  62. s->prior=r;
  63. r=s;
  64. }
  65. r->next=first;//循环链表建立完毕,将终端结点的指针域指向自身
  66. first->prior=r;
  67. }
  68. //遍历操作
  69. void CirLinkList::PrintList()//遍历操作,按序号依次输出各元素
  70. {
  71. CirNode *p = first->next;//工作指针p初始化
  72. while(p!=first)
  73. {
  74. if(p==first){
  75. p=p->next;
  76. continue;
  77. }
  78. cout<<p->data<"\t";
  79. p=p->next;//工作指针p后移,注意不能写作p++
  80. }
  81. }
  82. //从任意结点处遍历整个链表
  83. void CirLinkList::PrintCirNode(CirNode *node)
  84. {
  85. CirNode *p = node;
  86. cout<<p->data<<"\t";
  87. p=p->next;
  88. while(p!=node)
  89. {
  90. if(p==first){
  91. p=p->next;
  92. continue;
  93. }
  94. cout<<p->data<<"\t";
  95. p=p->next;
  96. }
  97. }
  98. //查找任意位置
  99. void CirLinkList::GetNode(int i)
  100. {
  101. CirNode *p = first->next; //工作指针p初始化
  102. int count = 1;//累加器count初始化
  103. while(count<i)
  104. {
  105. p = p->next;//工作指针p后移
  106. count++;
  107. }
  108. PrintCirNode(p);
  109. cout<<endl;
  110. /*
  111. CirNode *p = first->next;
  112. while(1)
  113. {
  114. p = p->next;
  115. if(p->data == i){
  116. PrintCirNode(p);
  117. break;
  118. }
  119. }*/
  120. }
  121. //从任意位置遍历链表
  122. void CirLinkList::RunPrintCirCirNode()
  123. {
  124. int locate;
  125. cout<<"请输入从第几个开始遍历整个链表:";
  126. cin>>locate;
  127. GetNode(locate);
  128. }
  129. //从任意位置查询结点的前驱和后继
  130. void CirLinkList::Print_NearBothNode(int i)
  131. {
  132. CirNode *p = first->next; //工作指针p初始化
  133. int count = 1;//累加器count初始化
  134. while(count<i)
  135. {
  136. p = p->next;//工作指针p后移
  137. count++;
  138. }
  139. cout<<"当前位置的前驱:"<<p->prior->data<<"当前位置:"<<p->data<<"当前位置的后继:"<<p->next->data<<endl;
  140. }
  141. //插入操作
  142. void CirLinkList::Insert(int i,DataType x)
  143. {
  144. CirNode *p=first,*s=nullptr;
  145. int count=0;
  146. while(count<i-1)
  147. {
  148. p = p->next; //工作指针后移
  149. count++;
  150. }
  151. s = new CirNode;s->data=x;//申请结点x,数据域为xx
  152. //s->next = p->next;p->next=s;//将结点s插入到结点p之后
  153. s->prior=p;
  154. s->next=p->next;
  155. p->next->prior=s;
  156. p->next=s;
  157. }
  158. //删除操作
  159. DataType CirLinkList::Delete(int i)
  160. {
  161. DataType x;
  162. CirNode*p = first->next;
  163. int count=0;
  164. while(p!=first && count<i-1)//查找第i-1个结点
  165. {
  166. p = p->next;
  167. count++;
  168. }
  169. if(!p)//结点p不存在或p的后继结点不存在
  170. throw "删除位置错误";
  171. else{
  172. p->prior->next=p->next;
  173. p->next->prior=p->prior;
  174. delete p;
  175. return x;
  176. }
  177. }
  178. int CirLinkList::symmetry(){
  179. int sym=1;
  180. CirNode *p=first->next, *q=first->prior;
  181. while((p!=q&&q!=p->next) && sym==1){
  182. if (p->data==q->data){
  183. p=p->next;
  184. q=q->prior;
  185. }
  186. else sym=0;
  187. }
  188. if(sym==1 && p->data!=q->data)
  189. sym=0;
  190. return sym;
  191. }
  192. int main()
  193. {
  194. int r[5]={1,2,8,2,5},i,x;
  195. DataType element_data;
  196. CirLinkList L{r,5};
  197. cout<<"当 前 链 表 的 数 据 为 : ";
  198. L.PrintList();//输出
  199. cout<<endl;
  200. if(L.symmetry())
  201. cout<<"该 链 表 对 称!";
  202. else
  203. cout<<"该 链 表 不 对 称!";
  204. return 0;
  205. }

调试代码实验结果图:

我是热爱学习的呵呵哒~如果你觉得文章很棒,对你有帮助的话,可以点赞+收藏+加关注喔~

如果文章有不正确的地方,欢迎交流指正,我将虚心请教~o(>ω<)o

我会定期更新文章,继续为您提供优质文章

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/593758
推荐阅读
相关标签
  

闽ICP备14008679号