链表习题:
1. 单链表反转
2. 链表中环的检测
3. 两个有序的链表合并
4. 删除链表倒数第 n 个结点
5. 求链表的中间结点
1 #include <iostream>
2 using namespace std;
3
4 typedef struct LNode
5 {
6 int data;
7 struct LNode *next;
8 }LNode,*Linklist;
9
10 //输出链表
11 void Printf_LNode(Linklist L)
12 {
13 LNode *p = L->next;
14 while(p)
15 {
16 if(!p->next)
17 {
18 cout<<p->data;
19 }
20 else cout<<p->data<<"->";
21 p = p->next;
22 }
23 cout<<endl;
24 }
25
26 //带环链表输出方式
27 void PrintfCircleLinklist(Linklist L)
28 {
29 int number = 0;
30 LNode *q = L->next;
31 while(q)
32 {
33 if(number == 9)
34 {
35 cout<<q->data;
36 break;
37 }
38 cout<<q->data<<"->";
39 number++;
40 q = q->next;
41 }
42 cout<<endl;
43 }
44 //后插法创建链表
45 Linklist CreatLinkList()
46 {
47
48 int n;
49 cout<<"请输入节点个数:"<<endl;
50 cin>>n;
51 Linklist L = new LNode;
52 L->next=nullptr;
53 LNode *r = L;
54 cout<<"请输入节点内容:"<<endl;
55 for(int i = 0;i < n;i++)
56 {
57 LNode *p = new LNode;
58 p->next = nullptr;
59 r->next = p;
60 r = p;
61 cin>>p->data;
62 }
63 return L;
64 }
65
66 //单链表反转
67 void Reversal(Linklist L)
68 {
69 cout<<"反转之前链表内容是:";
70 Printf_LNode(L);
71 Linklist LR;
72 LR = new LNode;
73 LR->next = nullptr;
74 LNode *p = L->next;
75 while(p)
76 {
77 LNode *s = new LNode;
78 s->next = LR->next;
79 s->data = p->data;
80 LR->next = s;
81 p = p->next;
82 }
83 cout<<"反转之后链表内容是:";
84 Printf_LNode(LR);
85 }
86
87 //创建一个带环的链表
88 Linklist CrearCircleLinklist()
89 {
90 Linklist L;
91 L = new LNode;
92 L->next = nullptr;
93 LNode *r = L;
94 LNode *c;
95 for(int i = 0; i < 6;i++)
96 {
97 LNode *p = new LNode;
98 p->next = nullptr;
99 r->next = p;
100 p->data = i;
101 r = p;
102 if(i == 4)
103 {
104 c = r;
105 }
106 }
107 r->next = c;
108 return L;
109 }
110 //链表中环的检测
111 bool HasCircle(Linklist L)
112 {
113 cout<<"检测链表内容为:";
114 LNode *pslow = L->next;
115 LNode *pfast =pslow->next;
116 for(;pslow&&pfast;pslow = pslow->next,pfast = pfast->next->next)
117 {
118 if(pslow == pfast)
119 {
120 PrintfCircleLinklist(L);
121 cout<<"检测结果:链表带环"<<endl;
122 return true;
123 }
124 }
125 Printf_LNode(L);
126 cout<<"检测结果:链表不带环"<<endl;
127 return false;
128 }
129
130 //链表合并
131 Linklist MergeLinklist()
132 {
133 cout<<"合并链表,先创建两个链表"<<endl;
134 Linklist L1,L2,L3;
135 L1 = CreatLinkList();
136 L2 = CreatLinkList();
137 L1 = L1->next;
138 L2 = L2->next;
139 L3 = new LNode;
140 L3->next = nullptr;
141 LNode *p = L3;
142 if(L1 == nullptr && L2 == nullptr)
143 {
144 return nullptr;
145 }
146 else if(L1 == nullptr && L2 != nullptr)
147 {
148 return L2;
149 }
150 else if(L1 != nullptr && L2 == nullptr)
151 {
152 return L1;
153 }
154 else
155 {
156 while(L1 && L2)
157 {
158 if(L1->data <= L2->data)
159 {
160 p->next = L1;
161 L1 = L1->next;
162 }
163 else
164 {
165 p->next = L2;
166 L2 = L2->next;
167 }
168 p = p->next;
169 }
170 }
171 p->next = L1 == nullptr ? L2 : L1;
172 return L3;
173 }
174 //求链表长度
175 int LinklistLength(Linklist L)
176 {
177 int length = 0;
178 LNode *p = L->next;
179 while(p)
180 {
181 length++;
182 p = p->next;
183 }
184 return length;
185 }
186 //删除节点
187 void DeleteLNode()
188 {
189 int pos;
190 Linklist L = CreatLinkList();
191 LNode *p = L;
192 cout<<"链表内容是:";
193 Printf_LNode(L);
194 cout<<"请输入你要删除倒数第几个节点:";
195 cin>>pos;
196 if(pos > LinklistLength(L))
197 {
198 cout<<"你要删除的节点不存在"<<endl;
199 return;
200 }
201 else if(pos == LinklistLength(L))
202 {
203 p->next = p->next->next;
204 }
205 else
206 {
207 for(int i = 0;i < (LinklistLength(L)- pos);i++,p = p->next);
208 p->next = p->next->next;
209 }
210 cout<<"删除之后链表内容是:";
211 Printf_LNode(L);
212 }
213 //寻找中间节点
214 void MiddleLNode()
215 {
216 Linklist L = CreatLinkList();
217 LNode *p = L->next;
218 cout<<"链表内容是:";
219 Printf_LNode(L);
220 if(LinklistLength(L) % 2 == 1)
221 {
222 for(int i = 0;i < LinklistLength(L)/2;i++,p = p->next);
223 cout<<"链表中间节点是:"<<p->data<<endl;
224 }
225 else
226 {
227 for(int i = 0; i < LinklistLength(L)/2-1;i++,p = p->next);
228 cout<<"链表中间节点是:"<<p->data<<"和"<<p->next->data<<endl;
229 }
230 }
231 int main()
232 {
233 cout<<"--------------------------------------------"<<endl;
234 cout<<"1.链表反转"<<endl;
235 Linklist L = CreatLinkList();
236 Reversal(L);
237 cout<<"-------------------分界线-------------------"<<endl;
238 cout<<"2.链表中环的检测"<<endl;
239 HasCircle(L);
240 HasCircle(CrearCircleLinklist());
241 cout<<"-------------------分界线-------------------"<<endl;
242 cout<<"3.两个有序链表的合并:"<<endl;
243 Linklist SumLinklist = MergeLinklist();
244 cout<<"链表合并之后的内容是:"<<endl;
245 Printf_LNode(SumLinklist);
246 cout<<"-------------------分界线-------------------"<<endl;
247 cout<<"4.删除链表倒数第n个节点"<<endl;
248 DeleteLNode();
249 cout<<"-------------------分界线-------------------"<<endl;
250 cout<<"5. 求链表的中间结点"<<endl;
251 MiddleLNode();
252 return 0;
253 }