1 #include<iostream>
2 #include<string>
3 #include<stdlib.h>
4
5 using namespace std;
6
7 typedef int ElemType;
8 typedef int Status;
9 #define OK 1
10 #define ERROR 0
11
12
13 //单链表的存储结构
14 typedef struct LNode
15 {
16 ElemType data; //结点的数据域
17 struct LNode *next; //结点的指针域
18 }LNode,*LinkList; //LinkList为指向结构体LNode的指针类型
19
20
21 //初始化
22 Status InitList(LinkList &L)
23 {
24 L = new LNode; //生成新结点作为头结点,用头指针L指向头结点
25
26 if (!L) //分配失败
27 return ERROR;
28
29 L->next = NULL; //头结点的指针域置空
30 return OK;
31 }
32
33 //判断是否为空链表
34 bool ListEmpty(LinkList L)
35 {
36 if(L->next == NULL)
37 return true;
38 else
39 return false;
40 }
41
42 //返回单链表的长度
43 int ListLength(LinkList L)
44 {
45 int length = 0;
46 LinkList q = L;
47 while(q->next != NULL)
48 {
49 q = q->next;
50 length++;
51 }
52 return length;
53 }
54
55 //前插法创建单链表
56 //逆位序输入n个元素的值,建立带表头结点的单链表L
57 void CreateList_H(LinkList &L,int n)
58 {
59 LinkList p;
60
61 L = new LNode;
62 L->next = NULL; //先建立一个带头结点的空链表
63
64 cout << "请依次输入" << n << "个元素:" << endl;
65
66 for (int i = 0; i < n; i++)
67 {
68 p = new LNode; //生成新结点*p
69 cin >> p->data; //输入元素值赋给新结点*p的数据域
70 p->next = L->next;
71 L->next = p; //将新结点*p插入到头结点之后 (注意次序不能颠倒!!!
72 }
73 }
74
75
76 //尾插法创建单链表
77 void CreateList_R(LinkList &L, int n)
78 {
79 LinkList s, r;
80
81 L = new LNode;
82 L->next = NULL; //先创建一个带头结点的空链表
83
84 r = L; //尾指针r指向头结点
85
86 cout << "请依次输入" << n << "个元素:" << endl;
87
88 for (int i = 0; i < n; i++)
89 {
90 s = new LNode;
91 cin >> s->data;
92
93 s->next = NULL;
94 r->next = s;
95
96 r = s; //更新r的指向,r指向新的尾节点s
97 }
98 }
99
100
101 //取值
102 //在带头结点的单链表L中根据序号i获取元素的值,用e返回L中第i个数据元素的值
103 Status GetElem(LinkList L, int i, ElemType &e)
104 {
105 LinkList p;
106
107 p = L->next; //初始化,p指向首元结点
108 int j = 1; //计数器
109 while (p && j < i)
110 {
111 p = p->next; //p指向下一个结点
112 j++;
113 }
114 if (!p || j > i)
115 return ERROR; //i值不合法,i>n 或 i<=0
116
117 e = p->data;
118 return OK;
119 }
120
121
122 //查找
123 //在带头结点的单链表L中查找值为e的元素
124 int LocateElem(LinkList L, ElemType e)
125 {
126 LinkList p;
127
128 p = L->next; //初始化,p指向首元结点
129
130 int n = 1;
131
132 while (p && p->data != e) //顺链域向后扫描,直到p为空或p所指向的结点数据域等于e
133 {
134 p = p->next;
135 n++;
136 }
137
138 if (!p)
139 return -1;
140
141 return n;
142 }
143
144
145 //插入
146 //在带头结点的单链表L中第i个位置插入值为e的新结点
147 Status ListInsert(LinkList &L, int i, ElemType e)
148 {
149 LinkList p;
150 p = L;
151 int j = 0;
152
153 while (p && (j < i - 1)) //查找第i-1个结点,p指向该结点
154 {
155 p = p->next;
156 j++;
157 }
158 if (!p || j > i - 1)
159 return ERROR;
160
161 LinkList s;
162 s = new LNode;
163
164 s->data = e;
165 s->next = p->next;
166 p->next = s;
167 //注意这里的次序!!!
168
169 return OK;
170 }
171
172
173 //删除
174 //在带头结点的单链表L中,删除第i个元素
175 Status ListDelete(LinkList &L, int i)
176 {
177 LinkList p, q;
178 p = L;
179 int j = 0;
180 while ((p->next) && (j < i - 1)) //查找第i-1个结点,p指向该结点
181 {
182 p = p->next;
183 j++;
184 }
185 if (!(p->next) || (j > i - 1))
186 return ERROR;
187
188 q = p->next;
189 p->next = q->next;
190
191 delete q;
192
193 return OK;
194 }
195
196 //单链表的销毁
197 void DestroyList(LinkList &L)
198 {
199 LinkList q;
200 while(L)
201 {
202 q = L;
203 L = L->next;
204 delete q;
205 }
206 L = NULL;
207 }
208
209 //清空单链表,仅保留头结点
210 void ClearList(LinkList &L)
211 {
212 LinkList q;
213 while(L->next)
214 {
215 q = L->next;
216 L->next = q->next;
217 delete q;
218 }
219 }
220
221 //单链表的输出
222 void PrintList(LinkList L)
223 {
224 LinkList p;
225
226 p = L->next;
227
228 while (p)
229 {
230 cout << p->data << " ";
231 p = p->next;
232 }
233 cout << endl;
234 }
235
236 int main()
237 {
238 int i, x, e, n, choose;
239 LinkList L;
240 L = NULL; //这里不初始化为空,后面操作的时候vs上会报错,不太懂╮(╯▽╰)╭
241
242 cout << "1. 初始化\n";
243
244 cout << "2. 前插法创建单链表\n";
245
246 cout << "3. 尾插法创建单链表\n";
247
248 cout << "4. 取值\n";
249
250 cout << "5. 查找\n";
251
252 cout << "6. 插入\n";
253
254 cout << "7. 删除\n";
255
256 cout << "8. 销毁\n";
257
258 cout << "9. 清空\n";
259
260 cout << "10. 输出\n";
261
262 cout << "0. 退出\n";
263
264 choose = -1;
265
266 while (choose != 0)
267 {
268 cout << "请选择操作:" << endl;
269 cin >> choose;
270
271 switch (choose)
272 {
273 case 1://初始化
274 if (InitList(L))
275 cout << "成功初始化一个空的单链表!\n";
276 cout << endl;
277 break;
278
279 case 2://前插法创建单链表
280 cout << "请输入所要创建的单链表的长度:";
281 cin >> n;
282 CreateList_H(L, n);
283 cout << endl;
284 break;
285
286 case 3://尾插法创建单链表
287 cout << "请输入所要创建的单链表的长度:";
288 cin >> n;
289 CreateList_R(L, n);
290 cout << endl;
291 break;
292
293 case 4://单链表的取值
294 cout << "请输入您要选取的元素的位置:";
295 cin >> i;
296 if (GetElem(L, i, e))
297 {
298 cout << "选取成功!" << endl;
299 cout << "第" << i << "个元素是:" << e << endl;
300 }
301 else
302 cout << "选取失败!" << endl;
303 cout << endl;
304 break;
305
306 case 5://单链表的查找
307 cout << "请输入您要查找的元素:";
308 cin >> x;
309 if (LocateElem(L, x) != -1)
310 {
311 cout << "查找成功!" << endl;
312 cout << "该元素所在位置为:" << LocateElem(L,x) << endl;
313 }
314 else
315 cout << "查找失败!" << endl;
316 cout << endl;
317 break;
318
319 case 6://单链表的插入
320 cout << "请输入选择插入的位置和元素:";
321 cin >> i >> x;
322 if (ListInsert(L, i, x))
323 cout << "插入成功!" << endl;
324 else
325 cout << "插入失败!" << endl;
326 cout << endl;
327 break;
328
329 case 7://单链表的删除
330 cout << "请输入所要删除的元素位置:";
331 cin >> i;
332 if (ListDelete(L, i))
333 cout << "删除成功!" << endl;
334 else
335 cout << "删除失败!" << endl;
336 cout << endl;
337 break;
338
339 case 8://单链表销毁
340 DestroyList(L);
341 cout << "销毁成功!" << endl;
342 break;
343
344 case 9://单链表的清空
345 ClearList(L);
346 cout << "清空成功!" << endl;
347 break;
348
349 case 10://单链表的输出
350 cout << "当前单链表中元素为:" << endl;
351 PrintList(L);
352 cout << endl;
353 break;
354 }
355 }
356 return 0;
357 }