單鏈表的12種基本操作 ...
C++單鏈表的操作
2017-12-25
1 // 單鏈表.cpp: 定義控制台應用程式的入口點。 2 //Author:kgvito 3 //Date: 2017.12.25 4 5 6 #include "stdafx.h" 7 #include<iostream> 8 using namespace std; 9 10 typedef int DataType; 11 #define Node ElemType 12 #define ERROR NULL 13 14 //構建一個節點類 15 class Node 16 { 17 public: 18 int data; //數據域 19 Node * next; //指針域 20 }; 21 22 //構建一個單鏈表類 23 class LinkList 24 { 25 public: 26 LinkList(); //構建一個單鏈表; 27 ~LinkList(); //銷毀一個單鏈表; 28 void CreateLinkList(int n); //創建一個單鏈表 29 void TravalLinkList(); //遍歷線性表 30 int GetLength(); //獲取線性表長度 31 bool IsEmpty(); //判斷單鏈表是否為空 32 ElemType * Find(DataType data); //查找節點 33 void InsertElemAtEnd(DataType data); //在尾部插入指定的元素 34 void InsertElemAtIndex(DataType data,int n); //在指定位置插入指定元素 35 void InsertElemAtHead(DataType data); //在頭部插入指定元素 36 void DeleteElemAtEnd(); //在尾部刪除元素 37 void DeleteAll(); //刪除所有數據 38 void DeleteElemAtPoint(DataType data); //刪除指定的數據 39 void DeleteElemAtHead(); //在頭部刪除節點 40 private: 41 ElemType * head; //頭結點 42 }; 43 44 //初始化單鏈表 45 LinkList::LinkList() 46 { 47 head = new ElemType; 48 head->data = 0; //將頭結點的數據域定義為0 49 head->next = NULL; //頭結點的下一個定義為NULL 50 } 51 52 //銷毀單鏈表 53 LinkList::~LinkList() 54 { 55 delete head; //刪除頭結點 56 } 57 58 //創建一個單鏈表 59 void LinkList::CreateLinkList(int n) 60 { 61 ElemType *pnew, *ptemp; 62 ptemp = head; 63 if (n < 0) { //當輸入的值有誤時,處理異常 64 cout << "輸入的節點個數有誤" << endl; 65 exit(EXIT_FAILURE); 66 } 67 for (int i = 0; i < n;i++) { //將值一個一個插入單鏈表中 68 pnew = new ElemType; 69 cout << "請輸入第" << i + 1 << "個值: " ; 70 cin >> pnew->data; 71 pnew->next = NULL; //新節點的下一個地址為NULL 72 ptemp->next = pnew; //當前結點的下一個地址設為新節點 73 ptemp = pnew; //將當前結點設為新節點 74 } 75 } 76 77 //遍歷單鏈表 78 void LinkList::TravalLinkList() 79 { 80 if (head == NULL || head->next ==NULL) { 81 cout << "鏈表為空表" << endl; 82 } 83 ElemType *p = head; //另指針指向頭結點 84 while (p->next != NULL) //當指針的下一個地址不為空時,迴圈輸出p的數據域 85 { 86 p = p->next; //p指向p的下一個地址 87 cout << p->data << " "; 88 } 89 } 90 91 //獲取單鏈表的長度 92 int LinkList::GetLength() 93 { 94 int count = 0; //定義count計數 95 ElemType *p = head->next; //定義p指向頭結點 96 while (p != NULL) //當指針的下一個地址不為空時,count+1 97 { 98 count++; 99 p = p->next; //p指向p的下一個地址 100 } 101 return count; //返回count的數據 102 } 103 104 //判斷單鏈表是否為空 105 bool LinkList::IsEmpty() 106 { 107 if (head->next == NULL) { 108 return true; 109 } 110 return false; 111 } 112 113 //查找節點 114 ElemType * LinkList::Find(DataType data) 115 { 116 ElemType * p = head; 117 if (p == NULL) { //當為空表時,報異常 118 cout << "此鏈表為空鏈表" << endl; 119 return ERROR; 120 } 121 else 122 { 123 while (p->next != NULL) //迴圈每一個節點 124 { 125 if (p->data == data) { 126 return p; //返回指針域 127 } 128 p = p->next; 129 } 130 return NULL; //未查詢到結果 131 } 132 } 133 134 //在尾部插入指定的元素 135 void LinkList::InsertElemAtEnd(DataType data) 136 { 137 ElemType * newNode = new ElemType; //定義一個Node結點指針newNode 138 newNode->next = NULL; //定義newNode的數據域和指針域 139 newNode->data = data; 140 ElemType * p = head; //定義指針p指向頭結點 141 if (head == NULL) { //當頭結點為空時,設置newNode為頭結點 142 head = newNode; 143 } 144 else //迴圈知道最後一個節點,將newNode放置在最後 145 { 146 while (p->next != NULL) 147 { 148 p = p->next; 149 } 150 p->next = newNode; 151 } 152 } 153 154 //在指定位置插入指定元素 155 void LinkList::InsertElemAtIndex(DataType data,int n) 156 { 157 if (n<1 || n>GetLength()) //輸入有誤報異常 158 cout << "輸入的值錯誤" << endl; 159 else 160 { 161 ElemType * ptemp = new ElemType; //創建一個新的節點 162 ptemp->data = data; //定義數據域 163 ElemType * p = head; //創建一個指針指向頭結點 164 int i = 1; 165 while (n > i) //遍歷到指定的位置 166 { 167 p = p->next; 168 i++; 169 } 170 ptemp->next = p->next; //將新節點插入到指定位置 171 p->next = ptemp; 172 } 173 } 174 175 //在頭部插入指定元素 176 void LinkList::InsertElemAtHead(DataType data) 177 { 178 ElemType * newNode = new ElemType; //定義一個Node結點指針newNode 179 newNode->data = data; 180 ElemType * p = head; //定義指針p指向頭結點 181 if (head == NULL) { //當頭結點為空時,設置newNode為頭結點 182 head = newNode; 183 } 184 newNode->next = p->next; //將新節點插入到指定位置 185 p->next = newNode; 186 } 187 188 //在尾部刪除元素 189 void LinkList::DeleteElemAtEnd() 190 { 191 ElemType * p = head; //創建一個指針指向頭結點 192 ElemType * ptemp = NULL; //創建一個占位節點 193 if (p->next == NULL) { //判斷鏈表是否為空 194 cout << "單鏈表空" << endl; 195 } 196 else 197 { 198 while (p->next != NULL) //迴圈到尾部的前一個 199 { 200 ptemp = p; //將ptemp指向尾部的前一個節點 201 p = p->next; //p指向最後一個節點 202 } 203 delete p; //刪除尾部節點 204 p = NULL; 205 ptemp->next = NULL; 206 } 207 } 208 209 //刪除所有數據 210 void LinkList::DeleteAll() 211 { 212 ElemType * p = head->next; 213 ElemType * ptemp = new ElemType; 214 while (p != NULL) //在頭結點的下一個節點逐個刪除節點 215 { 216 ptemp = p; 217 p = p->next; 218 head->next = p; 219 ptemp->next = NULL; 220 delete ptemp; 221 } 222 head->next = NULL; //頭結點的下一個節點指向NULL 223 } 224 225 //刪除指定的數據 226 void LinkList::DeleteElemAtPoint(DataType data) 227 { 228 ElemType * ptemp = Find(data); //查找到指定數據的節點位置 229 if (ptemp == head->next) { //判斷是不是頭結點的下一個節點,如果是就從頭部刪了它 230 DeleteElemAtHead(); 231 } 232 else 233 { 234 ElemType * p = head; //p指向頭結點 235 while (p->next != ptemp) //p迴圈到指定位置的前一個節點 236 { 237 p = p->next; 238 } 239 p->next = ptemp->next; //刪除指定位置的節點 240 delete ptemp; 241 ptemp = NULL; 242 } 243 244 } 245 246 //在頭部刪除節點 247 void LinkList::DeleteElemAtHead() 248 { 249 ElemType * p = head; 250 if (p == NULL || p->next == NULL) { //判斷是否為空表,報異常 251 cout << "該鏈表為空表" << endl; 252 } 253 else 254 { 255 ElemType * ptemp = NULL; //創建一個占位節點 256 p = p->next; 257 ptemp = p->next; //將頭結點的下下個節點指向占位節點 258 delete p; //刪除頭結點的下一個節點 259 p = NULL; 260 head->next = ptemp; //頭結點的指針更換 261 } 262 } 263 264 //測試函數 265 int main() 266 { 267 LinkList l; 268 int i; 269 cout << "1.創建單鏈表 2.遍歷單鏈表 3.獲取單鏈表的長度 4.判斷單鏈表是否為空 5.獲取節點\n"; 270 cout << "6.在尾部插入指定元素 7.在指定位置插入指定元素 8.在頭部插入指定元素\n"; 271 cout<<"9.在尾部刪除元素 10.刪除所有元素 11.刪除指定元素 12.在頭部刪除元素 0.退出" << endl; 272 do 273 { 274 cout << "請輸入要執行的操作: "; 275 cin >> i; 276 switch (i) 277 { 278 case 1: 279 int n; 280 cout << "請輸入單鏈表的長度: "; 281 cin >> n; 282 l.CreateLinkList(n); 283 break; 284 case 2: 285 l.TravalLinkList(); 286 break; 287 case 3: 288 cout << "該單鏈表的長度為" << l.GetLength() << endl; 289 break; 290 case 4: 291 if (l.IsEmpty() == 1) 292 cout << "該單鏈表是空表" << endl; 293 else 294 { 295 cout << "該單鏈表不是空表" << endl; 296 } 297 break; 298 case 5: 299 DataType data; 300 cout << "請輸入要獲取節點的值: "; 301 cin >> data; 302 cout << "該節點的值為" << l.Find(data)->data << endl; 303 break; 304 case 6: 305 DataType endData; 306 cout << "請輸入要在尾部插入的值: "; 307 cin >> endData; 308 l.InsertElemAtEnd(endData); 309 break; 310 case 7: 311 DataType pointData; 312 int index; 313 cout << "請輸入要插入的數據: "; 314 cin >> pointData; 315 cout << "請輸入要插入數據的位置: "; 316 cin >> index; 317 l.InsertElemAtIndex(pointData, index); 318 break; 319 case 8: 320 DataType headData; 321 cout << "請輸入要在頭部插入的值: "; 322 cin >> headData; 323 l.InsertElemAtHead(headData); 324 break; 325 case 9: 326 l.DeleteElemAtEnd(); 327 break; 328 case 10: 329 l.DeleteAll(); 330 break; 331 case 11: 332 DataType pointDeleteData; 333 cout << "請輸入要刪除的數據: "; 334 cin >> pointDeleteData; 335 l.DeleteElemAtPoint(pointDeleteData); 336 break; 337 case 12: 338 l.DeleteElemAtHead(); 339 break; 340 default: 341 break; 342 } 343 }while (i != 0); 344 345 system("pause"); 346 return 0; 347 }