1. 程式人生 > >輸入一個連結串列的頭結點,從尾到頭反過來列印每個結點的值——5

輸入一個連結串列的頭結點,從尾到頭反過來列印每個結點的值——5

    一般這樣的題,連結串列肯定不會是一個雙向連結串列還帶個迴圈什麼的,也就是隻給一個單鏈表的頭結點,然後從尾到頭輸出每個結點的值;

    如果從前往後去找最後一個結點,那找到了輸出然後就沒辦法往返回往頭部訪問了,因為只是個單鏈表;因此可以想到,用遞迴來實現:

#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資料以及查詢刪除插入等函式,執行程式可得如下結果:

wKioL1cgUc_zP30sAAAVdBxIpak003.png

    從上面的程式可以知道,將連結串列逆序輸出其實就是後插入的結點先輸出,最開始放進去的結點最後輸出,因此也就是後進先出的原則,可以用棧來實現,從頭開始遍歷連結串列,將結點一一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;}

執行程式可得如下結果:

wKiom1cgd8ryTugJAAAIV2OqMMY154.png

《完》