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

叁歲伎倆 2021-09-21 04:34 464阅读 0赞

双向链表(Double Linked List)

由两个指针域构成,分别指向前驱、后驱。如下图。
在这里插入图片描述

判断链表是否到头、到尾:list.next != null、list.prior != null
假设上图中间节点为q,则有: q = q->next->prior = q.prior.next

线性链表、单链表: https://blog.csdn.net/weixin_43217942/article/details/104856259

  1. #include <stdio.h>
  2. #define ERROR 0
  3. #define OK 1
  4. #define TRUE 1
  5. #define FALSE 0
  6. typedef int status;
  7. typedef int ElemType;
  8. typedef struct Node {
  9. ElemType data;//数据
  10. struct Node *prior;//前驱
  11. struct Node *next;//后驱
  12. } Node, *DLinkList;
  13. /* * 初始化List * 初始化时前后驱都需要设为 NULL * 指针创建出来不初始化,会随机到其他地址,之后时候指针会修改其他地方的数据 */
  14. void initList(DLinkList &L) {
  15. L = new Node;
  16. L->next = NULL;
  17. L->prior = NULL;
  18. }
  19. /* * 初始化L并创建n个元素 */
  20. void createList(DLinkList &L, int n) {
  21. //init L
  22. L = new Node;
  23. L->prior = NULL;
  24. L->next = NULL;
  25. DLinkList q, add_elem;
  26. q = L;
  27. for (int i = 0; i < n; i++) {
  28. add_elem = new Node;
  29. add_elem->prior = NULL;
  30. add_elem->next = NULL;
  31. scanf("%d", &add_elem->data);
  32. q->next = add_elem;
  33. add_elem->prior = q;
  34. q = q->next;
  35. }
  36. }
  37. /* * 在尾部添加元素 * 首先找到尾元素,然后添加即可 */
  38. status addLast(DLinkList &L, ElemType e) {
  39. DLinkList q = L;
  40. while (q && q->next != NULL) {
  41. q = q->next;
  42. }
  43. Node *add_elem = new Node;
  44. add_elem->prior = NULL;
  45. add_elem->next = NULL;
  46. add_elem->data = e;
  47. q->next = add_elem;
  48. add_elem->prior = q;
  49. return OK;
  50. }
  51. /* * 在第i处添加元素e * 首先找到第i个元素 * while执行完后q指向第i个元素 * 此处注意: q指向最后余割元素需特殊处理 */
  52. status addElem(DLinkList &L, int i, ElemType e) {
  53. DLinkList q;
  54. q = L;
  55. int j = 0;
  56. while (q && j < i) {
  57. q = q->next;
  58. j++;
  59. }
  60. Node *add_elem = new Node;
  61. add_elem->prior = NULL;
  62. add_elem->next = NULL;
  63. add_elem->data = e;
  64. // i<0 i>n
  65. if (!q || j > i) return ERROR;
  66. //处理i=0 或 i=n
  67. if (q->next == NULL) {
  68. q->next = add_elem;
  69. add_elem->prior = q;
  70. return OK;
  71. }
  72. add_elem->next = q;
  73. q->prior = add_elem;
  74. add_elem->prior = q->prior;
  75. q->prior->next = add_elem;
  76. return OK;
  77. }
  78. //在头部添加元素
  79. status addFirst(DLinkList &L, ElemType e) {
  80. Node *add_elem = new Node;
  81. add_elem->data = e;
  82. add_elem->next = L->next;
  83. L->next->prior = add_elem;
  84. add_elem->prior = L;
  85. L->next = add_elem;
  86. return OK;
  87. }
  88. /* * 将第i个元素的值设置为e * 首先找到第i个元素 * while执行完后q指向第i个元素 * 注意: 当i=0, 设置的是头元节点的data */
  89. status setElem(DLinkList &L, int i, ElemType e) {
  90. DLinkList q;
  91. q = L;
  92. int j = 0;
  93. while (q && j < i) {
  94. q = q->next;
  95. j++;
  96. }
  97. //i<0 i>n
  98. if (!q || j > i) return ERROR;
  99. q->data = e;
  100. return OK;
  101. }
  102. //获取第i个elem
  103. ElemType getElem(DLinkList L, int i) {
  104. DLinkList q;
  105. q = L;
  106. int j = 0;
  107. while (q && j < i) {
  108. q = q->next;
  109. j++;
  110. }
  111. //i<0 i>n
  112. if (!q || j > i) return ERROR;
  113. return q->data;
  114. }
  115. //删除第i个元素
  116. status delElem(DLinkList &L, int i) {
  117. if (L->next == NULL) return ERROR;
  118. DLinkList q = L;
  119. int j = 0;
  120. while (q && j < i) {
  121. q = q->next;
  122. j++;
  123. }
  124. //i<1 i>n
  125. if (!q || j > i) return ERROR;
  126. Node *del_node;
  127. del_node = q;
  128. //尾元素
  129. if (q->next == NULL) {
  130. q->prior->next = NULL;
  131. delete del_node;
  132. return OK;
  133. }
  134. //非尾元素 删除q.next
  135. q->next->prior = q->prior;
  136. q->prior->next = q->next;
  137. delete del_node;
  138. return OK;
  139. }
  140. //删除首元素
  141. status delFirst(DLinkList &L) {
  142. //空表
  143. if (L->next == NULL) return ERROR;
  144. //删除L.next
  145. Node *del_node = L->next;
  146. L->next->next->prior = L;
  147. L->next = L->next->next;
  148. delete del_node;
  149. return OK;
  150. }
  151. //删除尾原宿
  152. status delLast(DLinkList &L) {
  153. DLinkList q = L;
  154. while (q->next != NULL) {
  155. q = q->next;
  156. }
  157. Node *del_node = q;
  158. q->prior->next = NULL;
  159. delete del_node;
  160. return OK;
  161. }
  162. //链表大小
  163. //此处的参数L是DLinkList指针的拷贝,相当于DLinkList L = L2;
  164. int size(DLinkList L) {
  165. if (L->next == NULL) return 0;
  166. int n = 0;
  167. while (L->next != NULL) {
  168. L = L->next;
  169. n++;
  170. }
  171. return n;
  172. }
  173. status isEmpty(DLinkList L) {
  174. if (L->next == NULL)return TRUE;
  175. return FALSE;
  176. }
  177. void printList(DLinkList L) {
  178. printf("---正序遍历---\n");
  179. while (L->next != NULL) {
  180. printf("%d\n", L->next->data);
  181. L = L->next;
  182. }
  183. //测试prior指针是否正确
  184. // printf("---倒序遍历---\n");
  185. // while(L->prior!=NULL){
  186. // printf("%d\n", L->data);
  187. // L = L->prior;
  188. // }
  189. }
  190. int main() {
  191. DLinkList L;
  192. initList(L);
  193. addLast(L, 1);
  194. addLast(L, 2);
  195. addLast(L, 3);
  196. // delLast(L);
  197. // delFirst(L);
  198. // delElem(L, 1);
  199. // addFirst(L,0);
  200. // addElem(L,4,4);
  201. // setElem(L,3,33);
  202. // printf("%d\n",getElem(L,3));
  203. // printf("%d\n",size(L));
  204. // printf("%d\n",isEmpty(L));
  205. printList(L);
  206. // DLinkList L2;
  207. //输入三个元素
  208. // createList(L2, 3);
  209. //
  210. // printList(L2);
  211. return 0;
  212. }

Q&A 请指正!


想了解作者更多,请移步我的个人网站,欢迎交流、留言~
极客技术空间:https://elltor.com/

发表评论

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

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

相关阅读

    相关 数据结构双向

    > 前面我们已经学完了单向链表,知道了单向链表如何进行增删查改等基本功能,而今天,我们将要学习双向链表。 目录 1.链表的分类 2.双向链表定义 3.双向链表接口的实现

    相关 数据结构 双向

    做一个豁达而努力的自己。 双向链表的定义:在单链表的每个节点中,再设置一个指向其前驱节点的指针域。 线性表的双向链表的存储结构: typedef struct DulNo