双链表的开始节点示意图如下:
双链表的插入操作示意图如下:
双链表的删除操作示意图如下:
双链表的好处在于,如果需要在链表中,需要通过某个节点得到它的前驱节点时,双链表直接用prev属性就能找到;而单链表要做到这一点,必须再次从Head节点开始一个一个用Next向下找,因此双链表的复杂度从O(n)降到O(1),显然更有效率。
代码如下:
1 #include <iostream>
2 #include <string>
3 #include <cstring>
4 using namespace std;
5
6 struct dl_node
7 {
8 char name[20];
9 struct dl_node *pre, *next;
10 };
11 typedef dl_node d_node;
12
13 d_node* create_link(int n);
14 void print_node(d_node *head);
15 d_node* insert_node(d_node *head, char *p, char *inp);
16 d_node* delete_node(d_node *head, char *p);
17 d_node* modify_node(d_node *head, char *p, char *mdp);
18 d_node* search_node(d_node *head, char *p);
19 d_node* contray_link(d_node *head); // 逆置
20
21 int main()
22 {
23 d_node *head, *searchpoint;
24 int n;
25 int t=1, b;
26 char student_name[20];
27 char insert_name[20], modify_name[20];
28
29 cout<<"输入链表的长度,创建链表:";
30 cin>>n;
31 head = create_link(n);
32
33 while(t)
34 {
35 cout<<endl;
36 cout<<"请输入你想要的操作";
37 cout<<"1:插入;2:删除;3:修改;4:查找;5:逆置;6:打印;7:退出"<<endl;
38 cout<<"请输入:";
39 cin>>b;
40 switch(b){
41 case 1:
42 cout<<"输入你要插入的名字:";
43 cin>>insert_name;
44 cout<<"输入你想在哪个名字前面插入:";
45 cin>>student_name;
46 head = insert_node(head, student_name, insert_name);
47 break;
48 case 2:
49 cout<<"输入你要删除的名字:";
50 cin>>student_name;
51 head = delete_node(head, student_name);
52 break;
53 case 3:
54 cout<<"输入你要修改后的名字:";
55 cin>>modify_name;
56 cout<<"输入你想替换掉的名字:";
57 cin>>student_name;
58 head = modify_node(head, student_name, modify_name);
59 break;
60 case 4:
61 cout<<"输入你要查找的名字:";
62 cin>>student_name;
63 searchpoint = search_node(head, student_name);
64 break;
65 case 5:
66 cout<<"逆置链表"<<endl;
67 head = contray_link(head);
68 break;
69
70 case 6:
71 cout<<"打印列表"<<endl;
72 print_node(head);
73 break;
74
75 case 7:
76 t = 0;
77 cout<<"退出成功!"<<endl;
78 break;
79 default:
80 break;
81 }
82 }
83
84 return 0;
85 }
86
87 d_node* create_link(int n)
88 {
89 d_node *head=NULL, *newnode;
90 int i;
91
92 newnode = new d_node;
93 if (newnode == NULL)
94 {
95 cout<<"无空间申请"<<endl;
96 return NULL;
97 }
98
99 cout<<"输入第1个人的名字:";
100 cin>>newnode->name;
101 newnode->pre = NULL;
102 newnode->next = NULL;
103 head = newnode;
104
105 for (i=1; i<n; i++)
106 {
107
108 newnode->next = new d_node;
109 cout<<"输入第"<<i+1<<"个人的名字:";
110 cin>>newnode->next->name;
111 newnode->next->next = NULL;
112
113 newnode->next->pre = newnode;
114 newnode = newnode->next;
115 }
116
117 return head;
118 }
119
120 void print_node(d_node *head)
121 {
122 while (head != NULL)
123 {
124 cout<<head->name<<" ";
125 head = head->next;
126 }
127 cout<<endl;
128 }
129
130 d_node* insert_node(d_node *head, char *p, char *inp)
131 {
132 d_node *temp=head;
133 d_node *q, *newnode;
134
135 if ((q = search_node(temp, p)) == NULL)
136 cout<<"输入有误,找不到指定的插入点"<<endl;
137 else {
138 newnode = new d_node;
139 strcpy(newnode->name, inp);
140 if (q->pre == NULL)
141 {
142 newnode->next = q;
143 newnode->pre = q->pre;
144 q->pre = newnode;
145
146 head = newnode; // 注意移动head指针
147 }
148 else
149 {
150 newnode->next = q;
151 newnode->pre = q->pre;
152 q->pre->next = newnode;
153 q->pre = newnode;
154 }
155 }
156
157 return head;
158 }
159
160 d_node* delete_node(d_node *head, char *p)
161 {
162 d_node *temp=head;
163 d_node *q;
164
165 if ((q = search_node(temp, p)) == NULL)
166 cout<<"不存在删除的名字"<<endl;
167 else
168 {
169 if (q->pre == NULL)
170 {
171 q->next->pre = q->pre;
172 // head = q->next;
173 }
174 else if (q->next == NULL)
175 {
176 q->pre->next = q->next;
177 }
178 else
179 {
180 q->pre->next = q->next;
181 q->next->pre = q->pre;
182 }
183 delete(q);
184 }
185
186 return head;
187 }
188
189 d_node* modify_node(d_node *head, char *p, char *mdp)
190 {
191 d_node *temp=head;
192 d_node *q;
193
194 if((q = search_node(temp, p)) == NULL)
195 cout<<"不存在替换掉的名字"<<endl;
196 else
197 strcpy(q->name, mdp);
198
199 return head;
200 }
201
202 d_node* search_node(d_node *head, char *p)
203 {
204 while (head != NULL)
205 {
206 if (strcmp(head->name, p) == 0)
207 {
208 return head;
209 break;
210 }
211 head = head->next;
212 }
213
214 return NULL;
215 }
216
217 d_node* contray_link(d_node *head)
218 {
219 d_node *q=head, *temp;
220
221 while (q != NULL)
222 {
223 temp = q->pre;
224 q->pre = q->next;
225 q->next = temp;
226 head = q; // 头指针跟上
227 q = q->pre;
228 }
229
230 return head;
231 }