單鏈表反轉(遞迴和非遞迴)
阿新 • • 發佈:2019-01-11
單鏈表反轉有遞迴和非遞迴兩種演算法。
下面定義節點
typedef struct ListNode{
int value;
ListNode* next;
}ListNode;
在遞迴演算法中的做法是:
1找到最後一個節點和倒數第二個節點,把最後一個節點設為頭節點的後繼
2反轉這兩個節點
3倒數第三個和第四個節點重複執行步驟2
其中注意,連結串列是以節點後繼為NULL結束的,在更改指標的過程中要把改後的節點後繼改為NULL
程式碼如下:
void Inversion_Recursion(ListNode* p,ListNode* Head) { if(NULL == p) { return; } if(p->next==NULL) { Head->next=p; return;//找到最後一個節點 } Inversion_Recursion(p->next,Head); p->next->next=p;//反轉節點 p->next=NULL;//第一個節點反轉後其後繼應該為NULL }
非遞迴實現很簡單,只需要遍歷一遍連結串列,在遍歷過程中,把遍歷的節點一次插入到頭部。在這個過程之後,第一個節點成了最後節點,因此要特殊處理,改其後繼為NULL
void Inversion(ListNode* Head) { ListNode *current,*tmp; current=Head->next; if(current!=NULL)//反轉後第一個節點的後繼要為NULL { tmp=current; current=current->next; tmp->next=NULL; } while(current!=NULL) { tmp=current; current=current->next; tmp->next=Head->next; Head->next=tmp; } }
測試程式碼:
#include<iostream> #include<malloc.h> typedef struct ListNode{ int value; ListNode* next; }ListNode; int main() { ListNode* Head=(ListNode*)malloc(sizeof(ListNode)); if(Head==NULL) std::cout<<"malloc failed"<<std::endl; ListNode* tmp=Head; for(int i=1;i<=10;i++) { tmp->next=(ListNode*)malloc(sizeof(ListNode)); tmp->next->value=i; tmp->next->next=NULL; tmp=tmp->next; } Inversion_Recursion(Head->next,Head); Inversion(Head); tmp=Head->next; while(1){ std::cout<<tmp->value<<std::endl; if(tmp->next==NULL) break; tmp=tmp->next; } }