輸入一個連結串列的頭結點,從尾到頭反過來列印每個結點的值——5
阿新 • • 發佈:2019-01-05
一般這樣的題,連結串列肯定不會是一個雙向連結串列還帶個迴圈什麼的,也就是隻給一個單鏈表的頭結點,然後從尾到頭輸出每個結點的值;
如果從前往後去找最後一個結點,那找到了輸出然後就沒辦法往返回往頭部訪問了,因為只是個單鏈表;因此可以想到,用遞迴來實現:
#include <iostream>using namespace std;template <class T> //將連結串列的結點定義為模板類,實現程式碼的複用性struct ListNode{ T _data; ListNode<T>* _next;};template <class T>ListNode<T>* buy_node(T data) //建立結點{ ListNode<T>* tmp = new ListNode<T>; tmp->_data = data; tmp->_next = NULL; return tmp;}template <class T>void init_list(ListNode<T>** node, T data) //連結串列的初始化{ *node = buy_node(data);}template <class T>void push_node(ListNode<T>*& head, T data) //向連結串列中插入結點{ if(head == NULL) { init_list(&head, data); return; } ListNode<T>* tmp = head; while(tmp->_next != NULL) { tmp = tmp->_next; } tmp->_next = buy_node(data);}template <class T>void destroy_list(ListNode<T>*& head) //銷燬連結串列{ if(head != NULL) { ListNode<T>* cur = head; ListNode<T>* tmp = head; while(cur != NULL) { tmp = cur; cur = cur->_next; delete tmp; } head = NULL; }}template <class T>void print_list(ListNode<T>* head) //正序列印連結串列的資料{ while(head != NULL) { cout<<head->_data<<"->"; head = head->_next; } cout<<"NULL"<<endl;}template <class T>void ReversePrintList(ListNode<T>* head) //逆序列印連結串列,用遞迴{ if(head != NULL) { ReversePrintList(head->_next); cout<<head->_data<<"->"; } else cout<<"NULL->";}int main(){ ListNode<int>* list = NULL; push_node(list, 1); push_node(list, 2); push_node(list, 3); push_node(list, 4); push_node(list, 5); push_node(list, 6); push_node(list, 7); push_node(list, 8); push_node(list, 9); cout<<"print list: "; print_list(list); cout<<"reverse print list: "; ReversePrintList(list); cout<<endl; destroy_list(list); return 0;}
上面的栗子中只為了完成題目要求並沒有實現連結串列的其他操作,比如pop資料以及查詢刪除插入等函式,執行程式可得如下結果:
從上面的程式可以知道,將連結串列逆序輸出其實就是後插入的結點先輸出,最開始放進去的結點最後輸出,因此也就是後進先出的原則,可以用棧來實現,從頭開始遍歷連結串列,將結點一一push_back進棧裡面,然後再從棧頂取出資料,取到的就是連結串列的最後一個結點,再不斷地pop資料然後取棧頂;
上面的程式中用的是非類的變數,下面可以定義一個連結串列類來實現,而且當程式執行完後不用手動呼叫解構函式釋放空間:
#include <iostream>#include <vector>using namespace std;template <class T>struct ListNode //連結串列結點結構體{ T _data; ListNode<T>* _next; ListNode(T data) :_data(data) ,_next(NULL) {} };template <class T>class List //實現一個連結串列類{public: List() //預設建構函式 :_head(NULL) {} List(T data) //帶參的建構函式 :_head(new ListNode<T>(data)) {} ~List() //解構函式,釋放連結串列結點空間 { if(_head != NULL) { ListNode<T>* tmp = _head; ListNode<T>* cur = _head; while(cur != NULL) { tmp = cur; cur = cur->_next; delete tmp; } _head = NULL; } } void _push(T data) //在連結串列尾部push資料 { if(_head == NULL) { _head = new ListNode<T>(data); return; } ListNode<T>* tmp = _head; while(tmp->_next != NULL) tmp = tmp->_next; tmp->_next = new ListNode<T>(data); } void print_list() //正序輸出連結串列 { ListNode<T>* tmp = _head; while(tmp != NULL) { cout<<tmp->_data<<"->"; tmp = tmp->_next; } cout<<"NULL"<<endl; } void ReversePrintList() //逆序輸出連結串列 { vector<T> list; ListNode<T>* tmp = _head; while(tmp != NULL) //將連結串列結點依次放入棧中 { list.push_back(tmp->_data); tmp = tmp->_next; } cout<<"reverse print list:"<<endl; while(!list.empty()) //不斷地取棧頂元素,釋放棧頂元素 { cout<<list.back()<<"->"; list.pop_back(); } cout<<"NULL"<<endl; }private: ListNode<T>* _head;};int main(){ List<int> list(1); list._push(2); list._push(3); list._push(4); list._push(5); list._push(6); list._push(7); list._push(8); list._push(9); list.print_list(); list.ReversePrintList(); return 0;}
執行程式可得如下結果:
《完》