經典演算法學習——逆轉連結串列
阿新 • • 發佈:2019-01-09
連結串列在資料結構中是一種非常重要的線性資料結構,也是各類面試筆試中常常涉及的問題。其中最常見的一個問題就是“輸入一個連結串列的頭結點,從尾到頭反過來打印出每個節點的值”,簡單說就是逆轉連結串列。當然,有人會發現,這其實就是劍指Offer中的一道題。這道題的實現我已經上傳至 https://github.com/chenyufeng1991/ReverseLinkedList_Stack 。
這道題最經典的實現就是使用棧。在我們正向遍歷連結串列的每個節點的時候,分別把每一個節點入棧,等到所有節點入棧後,再從棧頂彈出每一個節點,此時彈出的節點順序就是連結串列從尾到頭的順序。而棧結構在C++中使用STL是很容易實現的,程式碼如下:
/** * 輸入一個連結串列的頭結點,從尾到頭列印連結串列的每一個節點 */ #include <iostream> #include <stdlib.h> #include <stack> using namespace std; typedef struct ListNode{ int element; struct ListNode *next; }Node; void CreateLinkedList(Node **head); void ReverseLinkedList(Node *pNode); int main(int argc, const char * argv[]) { Node *pList; CreateLinkedList(&pList); ReverseLinkedList(pList); return 0; } /** * 指標是指向一個變數在記憶體中的地址; * 指標的指標是指向一個指標在記憶體中的地址; */ void CreateLinkedList(Node **head) { cout<<"依次輸入數字建立連結串列,輸入<=0建立結束"<<endl; *head = (Node *)malloc(sizeof(Node)); memset(*head, 0, sizeof(int)); (*head)->next = NULL; Node *pInsert; Node *pMove; pInsert = (Node *)malloc(sizeof(Node)); memset(pInsert, 0, sizeof(Node)); pInsert->next = NULL; cin>>pInsert->element; pMove = *head; while (pInsert->element > 0) { pMove->next = pInsert; pMove = pInsert; pInsert = (Node *)malloc(sizeof(Node)); memset(pInsert, 0, sizeof(Node)); pInsert->next = NULL; cin>>pInsert->element; } } void ReverseLinkedList(Node *pNode) { stack<Node *> nodes; // 要入棧的節點是真正連結串列的第一個結點,而不是頭結點 pNode = pNode->next; while (pNode != NULL) { nodes.push(pNode); pNode = pNode->next; } while (!nodes.empty()) { Node *top = nodes.top(); cout<<top->element<<" "; nodes.pop(); } }
除上面的思路以外,還有一種辦法來實現:在遍歷當前連結串列的時候,取出該節點,用頭插法建立一個新連結串列,新連結串列就是原連結串列的逆序。這種實現可以參考我的另一篇部落格 C語言實現單鏈表的逆序列印(帶頭結點) 。