C++使用迭代和遞迴兩種方式實現連結串列逆序演算法
阿新 • • 發佈:2019-02-17
1.連結串列逆序的兩種演算法
C++實現一個連結串列逆序演算法
2.連結串列逆序演算法實現原理
如A->B->C->D->E,一般會有以下兩種思路,如下
思路1:
先取出連結串列的最後一個E,然後將E作為新連結串列的頭,
現在狀態為
原始連結串列:A->B->C->D
新連結串列:E
再取出原來連結串列的最後一個D,然後將D插入到新連結串列的最後位置,
現在狀態為
原始連結串列:A->B->C
新連結串列:E->D
依次類推,最後形成E->D->C->B->A
可以看出來,這個演算法的複雜度為O(n2)。
思路二:
取出原始連結串列的第一個節點A,然後將該節點作為新連結串列的頭節點。
現在狀態為
原始連結串列:B->C->D->E
新連結串列:A
然後同上,變為了下面的狀態
原始連結串列:C->D->E
新連結串列: B->A
原始連結串列:D->E
新連結串列: C->B->A
原始連結串列:E
新連結串列: D->C->B->A
原始連結串列:
新連結串列: E->D->C->B->A
這個只需要對原始連結串列遍歷一次,就完成了這個工作,所以這個演算法的複雜度為O(n)。
通過對上面狀態的變化分析,只要我們知道原始連結串列和新連結串列的頭節點,我們就可以從原始連結串列取出第一個節點,然後將節點插入到新連結串列的第一個位置,由於兩個連結串列的頭結點現在都已經變化,所以我們不能丟失新頭節點的地址。所以,我們要設定兩個變數分別記錄兩個連結串列的頭結點。下面程式中的old_head和 new_head分別表示原始連結串列的頭節點和新連結串列的頭節點。
// ListReverse.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include <stdio.h> #include <malloc.h> typedef struct Node { int data; struct Node* next; }Node; #define LIST_LEN 10 //連結串列長度 Node * List = NULL; //連結串列 //迭代方式 void reverse_ite(Node * list) { Node * old_head = NULL; //原來連結串列的頭 Node * new_head = NULL; //新連結串列的頭 Node * cur = list; //獲得原來連結串列的頭 //每次將原來連結串列的頭取出,並插入到新連結串列中,並且是新連結串列的頭 while (cur != NULL) { old_head = cur->next; //將原來連結串列的頭取出,並將第二個節點作為頭節點 cur->next = new_head; //將取出的頭設為新連結串列的頭 new_head = cur; //新連結串列的頭就是目前新連結串列的頭 cur = old_head; //接著處理 } List = new_head; } //遞迴方式 void reverse_recursive(Node * old_head, Node * new_head) { if (old_head == NULL) { List = new_head; return; } Node * tmp = old_head->next; //將原來連結串列的頭取出,並將第二個節點作為原來連結串列的頭節點用於下一層遞迴 old_head->next = new_head; //將取出的頭設為新連結串列的頭 reverse_recursive(tmp, old_head); //接著處理 } //生成連結串列 void make_list() { List = (Node *)malloc(sizeof(Node) * LIST_LEN); int i = 0; for (i = 0; i < (LIST_LEN - 1); i++) { (List + i)->data = i + 1; (List + i)->next = List + i + 1; } (List + LIST_LEN - 1)->data = LIST_LEN; (List + LIST_LEN - 1)->next = NULL; } //列印倆表的data void print_list() { Node * cur = List; while (cur != NULL) { printf("%d ", cur->data); cur = cur->next; } printf("\n"); } int main() { make_list(); print_list(); //迭代方式 reverse_ite(List); print_list(); //遞迴方式 reverse_recursive(List, NULL); print_list(); }
程式碼執行結果如下: