单链表反转(递归和非递归)

来源:互联网 发布:学电脑编程能干什么 编辑:程序博客网 时间:2024/06/04 17:49

单链表反转有递归和非递归两种算法。

下面定义节点

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. typedef struct ListNode{  
  2.     int value;  
  3.     ListNode* next;  
  4. }ListNode;  

在递归算法中的做法是:

1找到最后一个节点和倒数第二个节点,把最后一个节点设为头节点的后继

2反转这两个节点

3倒数第三个和第四个节点重复执行步骤2

其中注意,链表是以节点后继为NULL结束的,在更改指针的过程中要把改后的节点后继改为NULL

代码如下:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void Inversion_Recursion(ListNode* p,ListNode* Head)  
  2. {  
  3.     if(p->next==NULL)  
  4.     {  
  5.         Head->next=p;  
  6.         return;//找到最后一个节点  
  7.     }  
  8.     Inversion_Recursion(p->next,Head);  
  9.     p->next->next=p;//反转节点  
  10.     p->next=NULL;//第一个节点反转后其后继应该为NULL  
  11. }  

非递归实现很简单,只需要遍历一遍链表,在遍历过程中,把遍历的节点一次插入到头部。在这个过程之后,第一个节点成了最后节点,因此要特殊处理,改其后继为NULL

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. void Inversion(ListNode* Head)  
  2. {  
  3.     ListNode *current,*tmp;  
  4.     current=Head->next;  
  5.     if(current!=NULL)//反转后第一个节点的后继要为NULL  
  6.     {  
  7.         tmp=current;  
  8.         current=current->next;  
  9.         tmp->next=NULL;  
  10.     }  
  11.       
  12.     while(current!=NULL)  
  13.     {  
  14.         tmp=current;  
  15.         current=current->next;  
  16.         tmp->next=Head->next;  
  17.         Head->next=tmp;  
  18.     }  
  19. }  

测试代码:
[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<malloc.h>  
  3.   
  4. typedef struct ListNode{  
  5.     int value;  
  6.     ListNode* next;  
  7. }ListNode;  
  8.   
  9.   
  10. int main()  
  11. {  
  12.     ListNode* Head=(ListNode*)malloc(sizeof(ListNode));  
  13.     if(Head==NULL)  
  14.         std::cout<<"malloc failed"<<std::endl;  
  15.     ListNode* tmp=Head;  
  16.     for(int i=1;i<=10;i++)  
  17.     {  
  18.         tmp->next=(ListNode*)malloc(sizeof(ListNode));  
  19.         tmp->next->value=i;  
  20.         tmp->next->next=NULL;  
  21.         tmp=tmp->next;  
  22.     }  
  23.     Inversion_Recursion(Head->next,Head);  
  24.     Inversion(Head);  
  25.     tmp=Head->next;  
  26.     while(1){  
  27.         std::cout<<tmp->value<<std::endl;  
  28.         if(tmp->next==NULL)  
  29.             break;  
  30.         tmp=tmp->next;  
  31.     }  
  32.   

0 0