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 }