![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #ifndef _BLIST_H_ 2 #define _BLIST_H_ 3 4 #include <iostream> 5 6 using namespace std; 7 8 template<class T> 9 class List{ 10 11 private: 12 class Node{ 13 public: 14 T data; 15 Node * next; 16 Node * prev; 17 Node(const T & val=T()) :data(val),next(),prev(){} 18 //在此节点后面添加节点new_node; 19 void addNodeAfter( Node * new_node); 20 //删除此节点后面一个节点,并释放占用内存 21 void delNodeAfter(); 22 }; 23 24 private: 25 Node * head; 26 Node * tail; 27 size_t size_; 28 29 public: 30 //分别为head,tail new 一个初始化的Node,并互相链接. 31 List(); 32 33 /*read operation part 34 * 35 */ 36 //返回元素个数 37 size_t size() const; 38 //判断链表是否为空 39 bool isEmpty() const; 40 //读取链首元素的值,若没有元素,则返回head->data(后面以此处理); 41 const T & getFirst() const; 42 //读取链尾元素的值 43 const T & getLast() const; 44 //读取指定下标(1~size)处的值,若下标超出范围,则返回head->data 45 const T & valueAt(size_t index) const; 46 //依值返回节点 47 Node * getNodeByVal(const T & item) const; 48 //依值返回下标 49 size_t getIndexByVal(const T & item) const; 50 //依下标返回节点 51 Node * getNodeByIndex(size_t index) const; 52 //打印所有元素的值 53 void showAll() const; 54 55 /*write operation part 56 * 57 */ 58 //添加元素到链首 59 void addFirst(const T & item); 60 //添加元素到链尾 61 void addLast(const T & item); 62 //向指定下标处添加元素 63 void addAt(size_t index, const T & item); 64 //移除链首元素 65 T removeFirst(); 66 //移除链尾元素 67 T removeLast(); 68 //移除下标指定的元素 69 T removeAt(size_t index); 70 //移除同item等值的元素 71 T removeVal(const T & item); 72 //清理链表,释放内存。保留链首和链尾,以便再次使用. 73 void clear(); 74 //销毁链表 75 ~List(); 76 }; 77 78 template<class T> 79 //注意此处嵌套类的定义使用文法 80 void List<T>::Node::addNodeAfter(List<T>::Node * new_node) 81 { 82 new_node->prev = this; 83 new_node->next = next; 84 next->prev = new_node; 85 next = new_node; 86 } 87 88 template<class T> 89 void List<T>::Node::delNodeAfter() 90 { 91 next->next->prev = this; 92 delete next; 93 next = next->next; 94 } 95 96 template<class T> 97 List<T>::List() 98 { 99 head = new Node; 100 tail = new Node; 101 head->next = tail; 102 tail->prev = head; 103 size_ = 0; 104 } 105 106 template<class T> 107 size_t List<T>::size() const 108 { 109 return size_; 110 } 111 112 template<class T> 113 bool List<T>::isEmpty() const 114 { 115 return size_ == 0; 116 } 117 118 template<class T> 119 void List<T>::addFirst(const T & item) 120 { 121 Node * new_node = new Node(item); 122 head->addNodeAfter(new_node); 123 ++size_; 124 } 125 126 template<class T> 127 void List<T>::addLast(const T & item) 128 { 129 Node * new_node = new Node(item); 130 tail->prev->addNodeAfter(new_node); 131 ++size_; 132 } 133 134 template<class T> 135 void List<T>::addAt(size_t index, const T & item) 136 { 137 if(index <= 1) 138 addFirst(item); 139 else if(index > size_) 140 addLast(item); 141 else 142 { 143 Node * new_node = new Node(item); 144 Node * pos = getNodeByIndex(index); 145 pos->prev->addNodeAfter(new_node); 146 ++size_; 147 } 148 } 149 150 template<class T> 151 const T & List<T>::getFirst() const 152 { 153 return head->next->data; 154 } 155 156 template<class T> 157 const T & List<T>::getLast() const 158 { 159 return tail->prev->data; 160 } 161 162 template<class T> 163 const T & List<T>::valueAt(size_t index) const 164 { 165 Node * retNode = getNodeByIndex(index); 166 if(retNode == NULL) 167 return head->data; 168 return retNode->data; 169 } 170 171 template<class T> 172 //返回嵌套类类型要用 typename 关键字注明类型,不然编译器报错 173 typename List<T>::Node * List<T>::getNodeByVal(const T & item) const 174 { 175 Node * ret = head->next; 176 while(ret != tail) 177 { 178 if(ret->data == item) 179 return ret; 180 ret = ret->next; 181 } 182 return NULL; 183 } 184 185 template<class T> 186 size_t List<T>::getIndexByVal(const T & item) const 187 { 188 int ret = 0; 189 Node * current = head->next; 190 while(current != tail) 191 { 192 ++ret; 193 if(current->data == item) 194 return ret; 195 current = current->next; 196 } 197 return 0; 198 } 199 200 template<class T> 201 typename List<T>::Node * List<T>::getNodeByIndex(size_t index) const 202 { 203 if(index < 1 || index > size_) 204 return NULL; 205 Node * ret = head->next; 206 for(int i = 1; i < index; i++) 207 ret = ret->next; 208 return ret; 209 } 210 211 template<class T> 212 T List<T>::removeFirst() 213 { 214 if(isEmpty()) 215 { 216 cout << "empty data!\n"; 217 return T(); 218 } 219 T ret = getFirst(); 220 head->delNodeAfter(); 221 --size_; 222 return ret; 223 } 224 225 template<class T> 226 T List<T>::removeLast() 227 { 228 if(isEmpty()) 229 { 230 cout << "empty data!\n"; 231 return T(); 232 } 233 T ret = getLast(); 234 tail->prev->prev->delNodeAfter(); 235 --size_; 236 return ret; 237 } 238 239 template<class T> 240 T List<T>::removeAt(size_t index) 241 { 242 Node * del_node = getNodeByIndex(index); 243 if(del_node == NULL) 244 return head->data; 245 T ret = del_node->data; 246 del_node->prev->delNodeAfter(); 247 --size_; 248 return ret; 249 } 250 251 template<class T> 252 T List<T>::removeVal(const T & item) 253 { 254 Node * del_node = getNodeByVal(item); 255 if(del_node == NULL) 256 return head->data; 257 T ret = del_node->data; 258 del_node->prev->delNodeAfter(); 259 --size_; 260 return ret; 261 } 262 263 template<class T> 264 void List<T>::showAll() const 265 { 266 cout << "["; 267 if(isEmpty()) 268 { 269 cout << "]\n"; 270 return; 271 } 272 Node * temp = head->next; 273 while(temp != tail->prev) 274 { 275 cout << temp->data << ", "; 276 temp = temp->next; 277 } 278 cout << temp->data << "]\n"; 279 } 280 281 template<class T> 282 void List<T>::clear() 283 { 284 Node * del_node = NULL; 285 Node * temp = head->next; 286 while(temp != tail) 287 { 288 del_node = temp; 289 temp = temp->next; 290 delete del_node; 291 } 292 head->next = tail; 293 tail->prev = head; 294 size_ = 0; 295 } 296 297 template<class T> 298 List<T>::~List() 299 { 300 clear(); 301 delete head; 302 delete tail; 303 head = tail = NULL; 304 } 305 306 #endif
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include "blist.h" 2 3 #include <iostream> 4 #include <string> 5 using namespace std; 6 7 int main() 8 { 9 List<int> list; 10 list.addFirst(10); 11 list.addLast(20); 12 list.addLast(30); 13 list.addFirst(5); 14 list.addAt(1,3); 15 list.addAt(10,100); 16 cout << "list.size() = " << list.size() << endl; 17 cout << "getFirst = " << list.getFirst() << endl; 18 cout << "getLast = " << list.getLast() << endl; 19 for(int i = 0; i <= list.size() +1; i++) 20 cout << "valueAt("<< i << ") = " << list.valueAt(i) << endl; 21 cout << "getIndexByVal(30) = " << list.getIndexByVal(30) << endl; 22 list.showAll(); 23 list.removeAt(4); 24 cout << "After remove index 4\n"; 25 list.showAll(); 26 list.removeVal(5); 27 cout << "After remove value 5\n"; 28 list.showAll(); 29 cout << "After clear\n"; 30 list.clear(); 31 list.showAll(); 32 return 0; 33 }