Skip to content

Commit cb62111

Browse files
authored
Create 5.4.2维护链表尾指针.md
1 parent 0925c58 commit cb62111

File tree

1 file changed

+170
-0
lines changed

1 file changed

+170
-0
lines changed

5.4.2维护链表尾指针.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
- 维护链表尾指针
2+
- 问题:
3+
- head和tail分别是整数单链表的第一个和最后一个元素的全局指针。采用C语言为以下原型实现相应函数:
4+
5+
```cpp
6+
bool delete(Element *elem);
7+
bool insertAfter(Element *elem, int data);
8+
```
9+
10+
- delete的参数是待删除的元素。insert After的两个参数给出了要插入的新元素和对应的数据。能通过调用insert After并使用 NULL 作为元素参数来插入链表的开头。这些函数应该返回一个表示成功的布尔值。
11+
- 这些函数必须保持头尾指针一直指向最新位置。
12+
- 提示:
13+
- 普通情况:链表的长度 ≥ 3
14+
- 边界情况:代码需要考虑对于长度为0、1、2的链表是否能够正常工作。
15+
16+
参考代码:
17+
```cpp
18+
// 维护链表尾指针
19+
#include <iostream>
20+
#include <forward_list>
21+
struct Element{
22+
Element* next; // 指针
23+
int data; // 数据
24+
};
25+
26+
class my_list{
27+
public:
28+
bool delete_my(Element *elem);
29+
bool insertAfter(Element *elem, int data);
30+
bool delete_my_new(Element *elem);
31+
Element* GetHead();
32+
Element* GetTail();
33+
private:
34+
Element* head = nullptr;
35+
Element* tail = nullptr;
36+
Element* GetBeforeEndElement();
37+
};
38+
39+
Element* my_list::GetHead(){
40+
return this->head;
41+
}
42+
43+
Element* my_list::GetTail(){
44+
return this->tail;
45+
}
46+
47+
Element* my_list::GetBeforeEndElement(){
48+
if(this->head == nullptr || this->head == this->tail){
49+
return nullptr;
50+
}
51+
52+
Element* p = this->head;
53+
while(p->next != this->tail){
54+
p = p->next;
55+
}
56+
return p;
57+
}
58+
59+
// 书中的实现方式:
60+
// curPos 是一个用于迭代的指针,表示当前遍历到的节点,初始值为 nullptr。
61+
// ppNext 是一个指向 curPos 的指针的指针,表示当前节点的“next”指针的地址。它用于更新节点之间的连接。
62+
// 在循环中,首先检查是否找到了要删除的节点。如果找到了,就将 *ppNext 指向该节点的下一个节点,然后检查该节点是否是尾节点(即没有下一个节点),如果是,更新 tail 指针。
63+
// 如果当前位置 curPos 不为空,则将 ppNext 更新为 curPos 的“next”指针的地址,以便在下次迭代时能够更新当前节点的“next”指针。
64+
// 如果 curPos 为空,循环退出。
65+
// 最后,如果没有找到要删除的节点,返回 false。
66+
bool my_list::delete_my_new(Element* elem){
67+
if(!elem){
68+
return false;
69+
}
70+
71+
Element *curPos = nullptr, **ppNext = &this->head;
72+
while(true){
73+
if(*ppNext == elem){
74+
*ppNext = elem->next;
75+
if(!(elem->next)){
76+
this->tail = curPos;
77+
delete(elem);
78+
return true;
79+
}
80+
}
81+
if(!(curPos = *ppNext)){
82+
break;
83+
}
84+
ppNext = &(curPos->next);
85+
}
86+
return false;
87+
}
88+
89+
bool my_list::delete_my(Element *elem){
90+
if(elem == nullptr || this->head == nullptr || this->tail == nullptr){
91+
return false;
92+
}
93+
94+
if(elem == this->head){
95+
this->head = this->head->next;
96+
if(this->head->next == nullptr){
97+
this->tail = nullptr;
98+
}
99+
delete elem;
100+
return true;
101+
}
102+
103+
if(elem == this->tail){
104+
Element* beforeEnd = this->GetBeforeEndElement();
105+
if(beforeEnd != nullptr){
106+
beforeEnd->next = nullptr;
107+
this->tail = beforeEnd;
108+
delete elem;
109+
return true;
110+
}
111+
}
112+
113+
Element* p = this->head;
114+
while(p != nullptr && p->next != elem){
115+
p = p->next;
116+
}
117+
118+
if(p){
119+
p->next = elem->next;
120+
delete(elem);
121+
return true;
122+
}
123+
return false;
124+
};
125+
126+
bool my_list::insertAfter(Element *elem, int data){
127+
if(elem == NULL){
128+
Element* e = new Element;
129+
e->data = data;
130+
e->next = this->head;
131+
if(this->head == NULL){
132+
this->head = e;
133+
this->tail = e;
134+
return true;
135+
}
136+
}
137+
return false;
138+
}
139+
140+
int main(){
141+
my_list myList;
142+
143+
Element* e1 = new Element;
144+
e1->data = 10;
145+
e1->next = nullptr;
146+
147+
Element* e2 = new Element;
148+
e2->data = 20;
149+
e2->next = nullptr;
150+
151+
myList.insertAfter(nullptr, 5);
152+
myList.insertAfter(nullptr, 1);
153+
154+
// 删除第一个节点
155+
if (myList.delete_my(myList.GetHead())) {
156+
std::cout << "Deleted first element." << std::endl;
157+
} else {
158+
std::cout << "Failed to delete element." << std::endl;
159+
}
160+
161+
// 删除最后一个节点
162+
if (myList.delete_my(myList.GetTail())) {
163+
std::cout << "Deleted last element." << std::endl;
164+
} else {
165+
std::cout << "Failed to delete element." << std::endl;
166+
}
167+
168+
return 0;
169+
}
170+
```

0 commit comments

Comments
 (0)