【数据结构】双向循环链表实现

前端之家收集整理的这篇文章主要介绍了【数据结构】双向循环链表实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

先来看一下双向链表和双向循环链表的逻辑结构:

下面我们将用c/c++语言实现双向循环链表:

  1. #include <iostream>
  2. #include <malloc.h>
  3. #include <windows.h>
  4.  
  5. using namespace std;
  6.  
  7. typedef struct _DATA_//数据
  8. {
  9. char name[40];
  10. }Data,*pData;
  11.  
  12. typedef struct _NODE_//节点
  13. {
  14. Data data;//数据域
  15. //指针域
  16. _NODE_* pNext;//后继指针
  17. _NODE_* pPre;//前驱指针
  18. }Node,*pNode;
  19.  
  20. typedef struct _TABLE_//管理员
  21. {
  22. pNode pHead;//头指针(头节点)
  23. pNode pTail;//尾指针(尾节点)
  24.  
  25. int nodeCount;//节点数
  26. }Table,*pTable;
  27.  
  28.  
  29. //////////////////////
  30. //声明
  31. pNode createNode(Data data);//创建节点
  32. void linkNode(pTable pTableTemp,pNode pNodeNew);//将创建的节点插入链表
  33. void printList(pTable pTableTemp);//遍历链表
  34. int getNodeCount(pTable pTableTemp);//返回节点个数
  35. void freeList(pTable pTableTemp);//释放所有节点
  36.  
  37. pNode findNode(pTable pTableTemp,char* name);//查找节点
  38. void deleteNode(pTable pTableTemp,pNode pNodeTemp);//删除节点
  39. /////////////////////
  40. //测试
  41. int main(void)
  42. {
  43. Table table = {0};
  44. Data data = {0};
  45. char temp[40];
  46. for(int i = 0; i < 4; i++)
  47. {
  48. cout<<"input name:";
  49. cin>>data.name;
  50. pNode pNodeTemp = createNode(data);
  51. linkNode(&table,pNodeTemp);
  52. }
  53. printList(&table);
  54.  
  55. cout<<"input data to del:";
  56. cin>>temp;
  57. pNode pNodeDel = findNode(&table,temp);
  58. if(pNodeDel != NULL)
  59. {
  60. deleteNode(&table,pNodeDel);
  61. }
  62. printList(&table);
  63. freeList(&table);
  64. return 0;
  65. }
  66. ////////////////////////////////////////////
  67. //具体实现
  68. pNode createNode(Data data)
  69. {
  70. pNode pNodeNew = (pNode)malloc(sizeof(Node));//申请内存
  71. if(pNodeNew != NULL)//申请成功
  72. {
  73. pNodeNew->data = data;//数据域赋值
  74. pNodeNew->pNext = pNodeNew->pPre = NULL;//指针域赋值
  75. return pNodeNew;//返回新生成的节点
  76. }
  77. return NULL;//失败时返回空
  78. }
  79. void linkNode(pTable pTableTemp,pNode pNodeNew)//节点插入
  80. {
  81. if(pTableTemp->pHead == NULL)//如果头指针为空
  82. {
  83. pTableTemp->pHead = pTableTemp->pTail = pNodeNew;//头指针和尾指针均指向新节点
  84. pTableTemp->pHead->pPre = pTableTemp->pTail->pNext = pNodeNew;//对节点的指针域赋值(指向自身)
  85. }
  86. else//否则
  87. {
  88. pTableTemp->pTail->pNext = pNodeNew;//尾节点的后继指针指向新节点
  89. pTableTemp->pHead->pPre = pNodeNew;//头节点的前驱指针指向新节点
  90. pNodeNew->pPre = pTableTemp->pTail;//新节点的前驱指针指向尾节点
  91. pNodeNew->pNext = pTableTemp->pHead;//新节点的后继指针指向首节点
  92.  
  93. pTableTemp->pTail = pNodeNew;//尾指针后移,并指向新生成的节点
  94. }
  95. pTableTemp->nodeCount++;//节点数++
  96. }
  97. void printList(pTable pTableTemp)
  98. {
  99. pNode pNodeTemp = pTableTemp->pHead;
  100. for(int i = 0; i < pTableTemp->nodeCount; i++)
  101. {
  102. cout<<pNodeTemp->data.name<<" ";
  103. pNodeTemp = pNodeTemp->pNext;
  104. }
  105. cout<<endl;
  106. }
  107. int getNodeCount(pTable pTableTemp)
  108. {
  109. return pTableTemp->nodeCount;
  110. }
  111. void freeList(pTable pTableTemp)
  112. {
  113. if(pTableTemp != NULL)
  114. {
  115. pNode pNodeTemp = pTableTemp->pHead;
  116. pNode pNodeDel = NULL;
  117. for(int i = 0; i < pTableTemp->nodeCount; i++)
  118. {
  119. pNodeDel = pNodeTemp->pNext;
  120. free(pNodeTemp);
  121. pNodeTemp = pNodeDel;
  122. }
  123. }
  124. }
  125. pNode findNode(pTable pTableTemp,char* name)
  126. {
  127. pNode pNodeTemp = pTableTemp->pHead;
  128. int iOK = -1;
  129. for(int i = 0; i < pTableTemp->nodeCount; i++)
  130. {
  131. iOK = strcmp(name,pNodeTemp->data.name);
  132. if(iOK == 0)
  133. {
  134. return pNodeTemp;
  135. }
  136. else
  137. {
  138. pNodeTemp = pNodeTemp->pNext;
  139. }
  140. }
  141. return NULL;
  142. }
  143. void deleteNode(pTable pTableTemp,pNode pNodeTemp)
  144. {
  145. if(pNodeTemp == pTableTemp->pHead)//待删除节点为头节点
  146. {
  147. pTableTemp->pHead = pNodeTemp->pNext;
  148. pTableTemp->pTail->pNext = pTableTemp->pHead;
  149. }
  150. else if(pNodeTemp == pTableTemp->pTail)//待删除节点为尾节点
  151. {
  152. pTableTemp->pTail = pNodeTemp->pPre;
  153. pTableTemp->pHead->pPre = pTableTemp->pTail;
  154. }
  155. else//待删除节点为中间节点
  156. {
  157. pNodeTemp->pNext->pPre = pNodeTemp->pPre;
  158. pNodeTemp->pPre->pNext = pNodeTemp->pNext;
  159. }
  160. free(pNodeTemp);//释放节点
  161. pTableTemp->nodeCount--;
  162. }


需要注意的是,插入删除算法。
插入分两种情况,如果链表为空,逻辑结构如下图:

如果链表不为空,则逻辑结构如下:

应该针对不同情况分别处理.

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