编程之美-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,从无头单链表表中删除节点

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值