编程之美-3.4-从无头单链表中删除节点-单链表逆置

1. 简述

    假设有一个没有头指针的单链表。一个指针指向此单链表中间的一个节点(不是第一个,也不是最后一个节点)。请将该节点从单链表中删除。
    扩展题目:给定一个链表头指针,将单链表逆置。

2. 思路

    对于第一个问题,首先把要删除的节点内容交换到后面节点上去,然后将后面的节点删除。注意,如果当前删除的节点是最后一个节点的时候,是无法搞定的。

assert(Curr!=NULL && Curr->Link != NULL);
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)
     break;
   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;
}

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;
}

4 参考

    编程之美,3.4,从无头单链表表中删除节点

posted @ 2011-09-07 21:38  xiaodongrush  阅读(669)  评论(0编辑  收藏  举报