双链表因为多了个前向指针,需要考虑的特殊因素多了一倍
所以中间插入(这儿没写)和中间删除会比较复杂。
其它倒没什么特别的,代码如下。
测试代码
1 #include <iostream> 2 #include "double_linklist.h" 3 using namespace std; 4 using namespace doublelinklist; 5 template class DList<int>; 6 int main(void) 7 { 8 DList<int> number; 9 10 //测试插入 11 cout << "/*additem()*/" << endl; 12 number.additem(2); 13 number.additem(3); 14 number.additem(5); 15 number.additem(7); 16 number.additem(11); 17 number.additem(13); 18 number.additem(17); 19 number.traverse(); 20 cout << " " << flush; 21 number.reverse(); 22 cout << " /*end*/ " << flush; 23 24 //测试获取长度 25 cout << "/*length()*/" << endl; 26 cout << number.size() << endl; 27 cout << "/*end*/ " << flush; 28 29 //测试获得头元素 30 cout << "/*getfirst()*/" << endl; 31 cout << number.getfirst() << endl; 32 cout << "/*end*/ " << flush; 33 34 //测试删除存在的元素(头尾及中间元素各一) 35 cout << "/*remove()*/" << endl; 36 number.remove(2); 37 number.remove(5); 38 number.remove(17); 39 number.traverse(); 40 cout << " " << flush;; 41 number.reverse(); 42 cout << " /*end*/ " << flush; 43 44 //测试删除不存在的元素 45 cout << "/*remove()*/" << endl; 46 number.remove(19); 47 cout << "/*end*/ " << flush; 48 49 //测试清空,并测试从空表中删除元素 50 cout << "/*clear(),remove()*/" << endl; 51 number.clear(); 52 number.remove(2); 53 cout << "/*end*/ " << flush; 54 55 system("pause"); 56 } 57 58 double_linklist_driver
实现代码
1 #ifndef DOUBLELINKLIST 2 #define DOUBLELINKLIST 3 #include <iostream> 4 using namespace std; 5 6 namespace doublelinklist 7 { 8 9 //链表节点模板 10 template <typename T> struct Node 11 { 12 Node<T>() : next(nullptr),prev(nullptr){} 13 Node<T>(const T &item, Node<T>* ptrn = nullptr, Node<T>* ptrp = nullptr) : data(item), next(ptrn), prev(ptrp){} 14 T data; 15 Node<T>* next; 16 Node<T>* prev; 17 }; 18 //头节点及链表主体操作 19 template <typename T> class DList 20 { 21 //构造函数 22 public: 23 DList<T>() : length(0), front(nullptr){} 24 //接口 25 public: 26 //返回长度 27 unsigned int size()const{ return length; } 28 //返回头指针 29 Node<T>* begin()const{ return front; } 30 //判断是否为空 31 bool empty()const{ return length == 0; } 32 //获得头元素 33 T getfirst()const{ return front->data; } 34 //获得尾元素 35 T getlast()const{ return rear->data; } 36 //#查找元素所在地址 37 Node<T>* find(const T &item)const; 38 //#尾部加入新元素 39 bool additem(const T &item); 40 //#删除指定元素 41 bool remove(const T &item); 42 //#遍历顺序输出链表元素 43 void traverse()const; 44 //#遍历倒序输出链表元素 45 void reverse()const; 46 //清空链表 47 void clear(); 48 49 //辅助函数 50 private: 51 //#查找元素前驱 52 Node<T>* find_prev(const T& item)const; 53 //数据 54 private: 55 unsigned int length; 56 Node<T>* front; 57 Node<T>* rear; 58 }; 59 60 //如果元素为头元素或元素不存在则返回nullptr,否则返回前驱 61 template <typename T> Node<T>* DList<T>::find_prev(const T& item)const 62 { 63 if (length == 0) 64 return nullptr; 65 if (front->data == item) 66 return nullptr; 67 for (Node<T>* iter = front; iter->next != nullptr; iter = iter->next) 68 { 69 if (iter->next->data == item) 70 return iter; 71 } 72 return nullptr; 73 } 74 //调用find_prev,如果元素存在则返回地址,不存在则返回nullptr 75 template <typename T> Node<T>* DList<T>::find(const T &item)const 76 { 77 Node<T>* iter = find_prev(item); 78 if (length == 0) 79 return nullptr; 80 if (front->data == item) 81 return front; 82 return iter->next; 83 } 84 template <typename T> bool DList<T>::additem(const T &item) 85 { 86 Node<T>* pnew = new Node<T>(item); 87 //原链表无元素 88 //头尾指针均指向新节点,且新节点前后指针默认为nullptr 89 if (length == 0) 90 front = rear = pnew; 91 else 92 { 93 rear->next = pnew; 94 pnew->prev = rear; 95 rear = pnew; 96 } 97 ++length; 98 return true; 99 } 100 //删除操作相对复杂 101 template <typename T> bool DList<T>::remove(const T &item) 102 { 103 //先判断链表是否空避免front->data未定义 104 if (length == 0) 105 { 106 cout << "No data!" << endl; 107 return false; 108 } 109 Node<T>* iter = find_prev(item); 110 //find_prev返回nullptr,且首元素不等,说明链表中无此元素 111 if (iter == nullptr && front->data != item) 112 { 113 cout << "Can not find!" << endl; 114 return false; 115 } 116 Node<T>* save; 117 //如果元素是首元素 118 //则仅需将save后继(如果存在)的前向指针改为nullptr 119 //如果save无后继,说明链表删除后为空,将rear置空 120 if (front->data == item) 121 { 122 save = front; 123 front = front->next; 124 if (save != rear) 125 save->next->prev = nullptr; 126 else 127 rear = nullptr; 128 } 129 //如果元素不是首元素 130 //则save的前驱iter的后向指针需改指向save后继 131 //同时,save后继(如果存在)的前向指针改为指向save的前驱iter 132 //如果save无后继,则rear要指向新的尾节点 133 else 134 { 135 save = iter->next; 136 iter->next = save->next; 137 if (save != rear) 138 save->next->prev = iter; 139 else 140 rear = iter; 141 } 142 delete save; 143 --length; 144 return true; 145 } 146 template <typename T> void DList<T>::traverse()const 147 { 148 if (length != 0) 149 { 150 for (Node<T>* iter = front; iter != nullptr; iter = iter->next) 151 cout << iter->data << ends; 152 } 153 } 154 template <typename T> void DList<T>::reverse()const 155 { 156 if (length != 0) 157 { 158 for (Node<T>* iter = rear; iter != nullptr; iter = iter->prev) 159 cout << iter->data << ends; 160 } 161 } 162 template <typename T> void DList<T>::clear() 163 { 164 Node<T>* iter; 165 while (front != nullptr) 166 { 167 iter = front; 168 front = front->next; 169 delete iter; 170 } 171 front = rear = nullptr; 172 length = 0; 173 } 174 } 175 #endif