Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /