1. 程式人生 > >用C++寫的帶模板雙向鏈表

用C++寫的帶模板雙向鏈表

main 報錯 src for out rst 所有 else ddl

技術分享
  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
雙向鏈表

技術分享
 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 }
鏈表測試代碼

用C++寫的帶模板雙向鏈表