有关链表的知识可以点击我上篇文章这里就不再赘述LinkedList

在这里插入图片描述
在这里插入图片描述

  • 双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。

双向循环链表的可以点击我这篇文章这里就不再赘述DoubleLoopLinkList

在这里插入图片描述

  1. void addFirst(const T &e) {
  2. //新建一个节点让它前驱指向头,后继指向头的后继然后再让头的后继指向新建的节点,
  3. head->next = new Node<T>(e, head, head->next);
  4. //把新节点的后继节点的前驱指向新节点
  5. head->next->next->prev = head->next;
  6. ++size;
  7. }
  1. void add(const int index, const T &e) {
  2. assert(index >= 0 && index <= size);
  3. Node<T> *prevNode = head;
  4. for (int i = 0; i < index; ++i) {
  5. prevNode = prevNode->next;
  6. }
  7. prevNode->next = new Node<T>(e, prevNode, prevNode->next);
  8. prevNode->next->next->prev = prevNode->next;
  9. ++size;
  10. }
  1. void addLast(const T &e) {
  2. //
  3. tail->prev = new Node<T>(e, tail->prev, tail);
  4. tail->prev->prev->next = tail->prev;
  5. ++size;
  6. }
  1. T removeFirst() {
  2. return remove(0);//调不调都是O(1),就这吧。
  3. }
  1. T remove(int index) {
  2. assert(index >= 0 && index < size);
  3. //找到待删除节点的前一节点
  4. Node<T> *prevNode = head;
  5. for (int i = 0; i < index; ++i) {
  6. prevNode = prevNode->next;
  7. }
  8. //暂存要删除的节点
  9. Node<T> *retNode = prevNode->next;
  10. T temp = retNode->e;
  11. //前一节点的后继指向待删除节点的后继
  12. prevNode->next = retNode->next;
  13. //后一节点的前驱指向待删除节点的前驱
  14. retNode->next->prev = retNode->prev;
  15. retNode->next = nullptr;
  16. retNode->prev = nullptr;
  17. --size;
  18. delete retNode;
  19. retNode = nullptr;
  20. return temp;
  21. }
  1. T removeLast() {
  2. //先暂存要删除的节点
  3. Node<T> *retNode = tail->prev;
  4. T temp = retNode->e;
  5. //尾指针的前驱指向待删除的前驱
  6. tail->prev = retNode->prev;
  7. 待删除节点前面一节点的后继指向尾指针
  8. retNode->prev->next = tail;
  9. retNode->next = nullptr;
  10. retNode->prev = nullptr;
  11. delete retNode;
  12. retNode = nullptr;
  13. --size;
  14. return temp;
  15. }
  1. //
  2. // Created by cheng on 2021/7/5.
  3. //
  4. #ifndef LINKEDLIST_TEST_H
  5. #define LINKEDLIST_TEST_H
  6. #include <assert.h>
  7. template<typename T>
  8. class Node {
  9. public:
  10. T e;
  11. Node *prev;
  12. Node *next;
  13. Node() : e(0), prev(nullptr), next(nullptr) {
  14. }
  15. Node(const T &E) : e(E), prev(nullptr), next(nullptr) {
  16. }
  17. Node(const T &E, Node<T> *Prev, Node<T> *Next) : e(E), prev(Prev), next(Next) {
  18. }
  19. };
  20. template<typename T>
  21. class DoubleLinkedList {
  22. public:
  23. DoubleLinkedList() : size(0) {
  24. head = new Node<T>(0, nullptr, head);
  25. tail = new Node<T>(0, tail, nullptr);
  26. }
  27. constexpr int getSize() const {
  28. return size;
  29. }
  30. constexpr bool isEmpty() const {
  31. return size == 0;
  32. }
  33. void add(const int index, const T &e) {
  34. assert(index >= 0 && index <= size);
  35. Node<T> *prevNode = head;
  36. for (int i = 0; i < index; ++i) {
  37. prevNode = prevNode->next;
  38. }
  39. prevNode->next = new Node<T>(e, prevNode, prevNode->next);
  40. prevNode->next->next->prev = prevNode->next;
  41. ++size;
  42. }
  43. void addFirst(const T &e) {
  44. head->next = new Node<T>(e, head, head->next);
  45. head->next->next->prev = head->next;
  46. ++size;
  47. }
  48. void addLast(const T &e) {
  49. tail->prev = new Node<T>(e, tail->prev, tail);
  50. tail->prev->prev->next = tail->prev;
  51. ++size;
  52. }
  53. void set(const int index, const T &e) {
  54. assert(index >= 0 && index < size);
  55. Node<T> *cur = head->next;
  56. for (int i = 0; i < index; ++i) {
  57. cur = cur->next;
  58. }
  59. cur->e = e;
  60. }
  61. void setFirst(const T &e) {
  62. head->next->e = e;
  63. }
  64. void setLast(const T &e) {
  65. tail->prev->e = e;
  66. }
  67. bool contains(const T &e) const {
  68. Node<T> *cur = head->next;
  69. while (cur != nullptr) {
  70. if (cur->e = e) {
  71. return true;
  72. }
  73. cur = cur->next;
  74. }
  75. return false;
  76. }
  77. T get(const int index) const {
  78. assert(index >= 0 && index < size);
  79. Node<T> *cur = head->next;
  80. for (int i = 0; i < index; ++i) {
  81. cur = cur->next;
  82. }
  83. return cur->e;
  84. }
  85. T getFirst() const {
  86. return head->next->e;
  87. }
  88. T getLast() const {
  89. return tail->prev->e;
  90. }
  91. T remove(int index) {
  92. assert(index >= 0 && index < size);
  93. Node<T> *prevNode = head;
  94. for (int i = 0; i < index; ++i) {
  95. prevNode = prevNode->next;
  96. }
  97. Node<T> *retNode = prevNode->next;
  98. prevNode->next = retNode->next;
  99. retNode->next->prev = retNode->prev;
  100. retNode->next = nullptr;
  101. retNode->prev = nullptr;
  102. --size;
  103. T temp = retNode->e;
  104. delete retNode;
  105. retNode = nullptr;
  106. return temp;
  107. }
  108. T removeFirst() {
  109. return remove(0);
  110. }
  111. T removeLast() {
  112. Node<T> *retNode = tail->prev;
  113. T temp = retNode->e;
  114. tail->prev = retNode->prev;
  115. retNode->prev->next = tail;
  116. retNode->next = nullptr;
  117. retNode->prev = nullptr;
  118. delete retNode;
  119. retNode = nullptr;
  120. --size;
  121. return temp;
  122. }
  123. ~DoubleLinkedList() {
  124. Node<T> *cur = head->next;
  125. Node<T> *temp;
  126. while (cur != nullptr) {
  127. temp = cur->next;
  128. delete cur;
  129. cur = temp;
  130. }
  131. head->next = nullptr;
  132. head->prev = nullptr;
  133. tail->prev = nullptr;
  134. tail->next = nullptr;
  135. delete head;
  136. head = nullptr;
  137. delete tail;
  138. tail = nullptr;
  139. }
  140. void print() {
  141. Node<T> *prevNode = head;
  142. std::cout << "LinkedList: size = " << size << std::endl;
  143. std::cout << "[";
  144. for (int i = 0; i < size; ++i) {
  145. prevNode = prevNode->next;
  146. std::cout << prevNode->e;
  147. if (i < size - 1) {
  148. std::cout << ", ";
  149. }
  150. }
  151. std::cout << "]" << std::endl;
  152. }
  153. private:
  154. Node<T> *head, *tail;
  155. int size;
  156. };
  157. #endif //LINKEDLIST_TEST_H
  1. //
  2. // Created by cheng on 2021/7/5.
  3. //
  4. #ifndef LINKEDLIST_DOUBLELINKEDLIST_H
  5. #define LINKEDLIST_DOUBLELINKEDLIST_H
  6. #include <assert.h>
  7. template<typename T>
  8. class Node {
  9. public:
  10. T e;
  11. Node *prev;
  12. Node *next;
  13. Node() : e(0), prev(nullptr), next(nullptr) {}
  14. Node(const T &E) : e(E), prev(nullptr), next(nullptr) {}
  15. Node(const T &E, Node<T> *Prev, Node<T> *Next) : e(E), prev(Prev), next(Next) {}
  16. };
  17. template<typename T>
  18. class DoubleLinkedList {
  19. public:
  20. DoubleLinkedList() : size(0) {
  21. dummyHead = new Node<T>(0, nullptr, dummyHead);
  22. }
  23. constexpr int getSize() const {
  24. return size;
  25. }
  26. constexpr bool isEmpty() const {
  27. return size == 0;
  28. }
  29. void add(const int index, const T &e) {
  30. assert(index >= 0 && index <= size);
  31. Node<T> *prevNode = dummyHead;
  32. for (int i = 0; i < index; ++i) {
  33. prevNode = prevNode->next;
  34. }
  35. prevNode->next = new Node<T>(e, prevNode, prevNode->next);
  36. prevNode->next->next->prev = prevNode->next;
  37. ++size;
  38. }
  39. void addFirst(const T &e) {
  40. add(0, e);
  41. }
  42. void addLast(const T &e) {
  43. add(size, e);
  44. }
  45. void set(const int index, const T &e) {
  46. assert(index >= 0 && index < size);
  47. Node<T> *cur = dummyHead->next;
  48. for (int i = 0; i < index; ++i) {
  49. cur = cur->next;
  50. }
  51. cur->e = e;
  52. }
  53. void setFirst(const T &e) {
  54. set(0, e);
  55. }
  56. void setLast(const T &e) {
  57. set(size, e);
  58. }
  59. bool contains(const T &e) const {
  60. Node<T> *cur = dummyHead->next;
  61. while (cur != nullptr) {
  62. if (cur->e = e) {
  63. return true;
  64. }
  65. cur = cur->next;
  66. }
  67. return false;
  68. }
  69. T get(const int index) const {
  70. assert(index >= 0 && index < size);
  71. Node<T> *cur = dummyHead->next;
  72. for (int i = 0; i < index; ++i) {
  73. cur = cur->next;
  74. }
  75. return cur->e;
  76. }
  77. T getFirst() const {
  78. return get(0);
  79. }
  80. T getLast() const {
  81. return get(size - 1);
  82. }
  83. T remove(int index) {
  84. assert(index >= 0 && index < size);
  85. Node<T> *prevNode = dummyHead;
  86. for (int i = 0; i < index; ++i) {
  87. prevNode = prevNode->next;
  88. }
  89. Node<T> *retNode = prevNode->next;
  90. prevNode->next = retNode->next;
  91. retNode->next->prev = retNode->prev;
  92. retNode->next = nullptr;
  93. retNode->prev = nullptr;
  94. --size;
  95. T temp = retNode->e;
  96. delete retNode;
  97. retNode = nullptr;
  98. return temp;
  99. }
  100. T removeFirst() {
  101. return remove(0);
  102. }
  103. T removeLast() {
  104. return remove(size - 1);
  105. }
  106. ~DoubleLinkedList() {
  107. Node<T> *cur = dummyHead->next;
  108. Node<T> *temp;
  109. while (cur != nullptr) {
  110. temp = cur->next;
  111. delete cur;
  112. cur = temp;
  113. }
  114. dummyHead->next = nullptr;
  115. dummyHead->prev = nullptr;
  116. delete dummyHead;
  117. dummyHead = nullptr;
  118. }
  119. void print() {
  120. Node<T> *prevNode = dummyHead;
  121. std::cout << "LinkedList: size = " << size << std::endl;
  122. std::cout << "[";
  123. for (int i = 0; i < size; ++i) {
  124. prevNode = prevNode->next;
  125. std::cout << prevNode->e;
  126. if (i < size - 1) {
  127. std::cout << ", ";
  128. }
  129. }
  130. std::cout << "]" << std::endl;
  131. }
  132. private:
  133. Node<T> *dummyHead;
  134. int size;
  135. };
  136. #endif //LINKEDLIST_DOUBLELINKEDLIST_H

版权声明:本文为chengmf原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/chengmf/p/14977506.html