1. 简述
假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点(不是第一个,也不是最后一个节点)。请将该节点从单链表中删除。
扩展题目:给定一个链表头指针,将单链表逆置。
2. 思路
对于第一个问题,首先把要删除的节点内容交换到后面节点上去,然后将后面的节点删除。注意,如果当前删除的节点是最后一个节点的时候,是无法搞定的。
assert(Curr
!=
NULL
&&
Curr
->
Link
!=
NULL);
swap(Curr -> value, Curr -> Link -> value);
Tmp = Curr -> Link;
Curr -> Link = Tmp -> Link;
delete Tmp;
swap(Curr -> value, Curr -> Link -> value);
Tmp = Curr -> Link;
Curr -> Link = Tmp -> Link;
delete Tmp;
对于第二个问题,也很简单,三个指针:Prev、Head和Next,分别指向前面的元素、当前元素和后面元素。Head是头指针,最后Head指向链表逆置后的头。注意,如果Head用函数参数传递,需要指针的指针或者指针的引用。
Node* Prev
=
NULL;
Node* Next;
while (Head) {
Next = Head -> Link;
Head -> Link = Prev;
if(Next == NULL)
Node* Next;
while (Head) {
Next = Head -> Link;
Head -> Link = Prev;
if(Next == NULL)
break;
Prev = Head;
Head = Next;
}
Prev = Head;
Head = Next;
}
如果不加if判断,那么最后Head移动到逆置前,最后面的空指针上去了,实际上,此时Prev中正好是逆置前,最后面得一个节点。上面的那个实现,每次循环都要判断个if,这个实现只要最后一次赋值,所以这个实现更好一些。
void
reverse(Node
*&
Head) {
Node * Prev = NULL;
Node * Next;
while (Head) {
Next = Head -> link;
Head -> link = Prev;
Prev = Head;
Head = Next;
}
Head = Prev;
}
Node * Prev = NULL;
Node * Next;
while (Head) {
Next = Head -> link;
Head -> link = Prev;
Prev = Head;
Head = Next;
}
Head = Prev;
}
3. 实现和测试
#include
<
iostream
>
using namespace std;
struct Node {
int value;
Node * link;
};
void reverse(Node *& Head) {
Node * Prev = NULL;
Node * Next;
while (Head) {
Next = Head -> link;
Head -> link = Prev;
if (Next == NULL) // 这一步很重要,避免Head移动到空指针上面去!!
break ;
Prev = Head;
Head = Next;
}
}
int main() {
Node * Head;
Head = new Node; Head -> value = 0 ;
Head -> link = new Node; Head -> link -> value = 1 ; Head -> link -> link = NULL;
// print head
Node * tmp = Head;
while (tmp) {
cout << tmp -> value << " " ;
tmp = tmp -> link;
}
cout << endl;
// reverse
reverse(Head);
// print head
tmp = Head;
while (tmp) {
cout << tmp -> value << " " ;
tmp = tmp -> link;
}
cout << endl;
// wait
system( " PAUSE " );
return 0 ;
}
using namespace std;
struct Node {
int value;
Node * link;
};
void reverse(Node *& Head) {
Node * Prev = NULL;
Node * Next;
while (Head) {
Next = Head -> link;
Head -> link = Prev;
if (Next == NULL) // 这一步很重要,避免Head移动到空指针上面去!!
break ;
Prev = Head;
Head = Next;
}
}
int main() {
Node * Head;
Head = new Node; Head -> value = 0 ;
Head -> link = new Node; Head -> link -> value = 1 ; Head -> link -> link = NULL;
// print head
Node * tmp = Head;
while (tmp) {
cout << tmp -> value << " " ;
tmp = tmp -> link;
}
cout << endl;
// reverse
reverse(Head);
// print head
tmp = Head;
while (tmp) {
cout << tmp -> value << " " ;
tmp = tmp -> link;
}
cout << endl;
// wait
system( " PAUSE " );
return 0 ;
}
4 参考
编程之美,3.4,从无头单链表表中删除节点