您好,登錄后才能下訂單哦!
一般這樣的題,鏈表肯定不會(huì)是一個(gè)雙向鏈表還帶個(gè)循環(huán)什么的,也就是只給一個(gè)單鏈表的頭結(jié)點(diǎn),然后從尾到頭輸出每個(gè)結(jié)點(diǎn)的值;
如果從前往后去找最后一個(gè)結(jié)點(diǎn),那找到了輸出然后就沒辦法往返回往頭部訪問了,因?yàn)橹皇莻€(gè)單鏈表;因此可以想到,用遞歸來實(shí)現(xiàn):
#include <iostream> using namespace std; template <class T> //將鏈表的結(jié)點(diǎn)定義為模板類,實(shí)現(xiàn)代碼的復(fù)用性 struct ListNode { T _data; ListNode<T>* _next; }; template <class T> ListNode<T>* buy_node(T data) //創(chuàng)建結(jié)點(diǎn) { 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) //向鏈表中插入結(jié)點(diǎn) { 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) //正序打印鏈表的數(shù)據(jù) { 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; }
上面的栗子中只為了完成題目要求并沒有實(shí)現(xiàn)鏈表的其他操作,比如pop數(shù)據(jù)以及查找刪除插入等函數(shù),運(yùn)行程序可得如下結(jié)果:
從上面的程序可以知道,將鏈表逆序輸出其實(shí)就是后插入的結(jié)點(diǎn)先輸出,最開始放進(jìn)去的結(jié)點(diǎn)最后輸出,因此也就是后進(jìn)先出的原則,可以用棧來實(shí)現(xiàn),從頭開始遍歷鏈表,將結(jié)點(diǎn)一一push_back進(jìn)棧里面,然后再從棧頂取出數(shù)據(jù),取到的就是鏈表的最后一個(gè)結(jié)點(diǎn),再不斷地pop數(shù)據(jù)然后取棧頂;
上面的程序中用的是非類的變量,下面可以定義一個(gè)鏈表類來實(shí)現(xiàn),而且當(dāng)程序運(yùn)行完后不用手動(dòng)調(diào)用析構(gòu)函數(shù)釋放空間:
#include <iostream> #include <vector> using namespace std; template <class T> struct ListNode //鏈表結(jié)點(diǎn)結(jié)構(gòu)體 { T _data; ListNode<T>* _next; ListNode(T data) :_data(data) ,_next(NULL) {} }; template <class T> class List //實(shí)現(xiàn)一個(gè)鏈表類 { public: List() //默認(rèn)構(gòu)造函數(shù) :_head(NULL) {} List(T data) //帶參的構(gòu)造函數(shù) :_head(new ListNode<T>(data)) {} ~List() //析構(gòu)函數(shù),釋放鏈表結(jié)點(diǎn)空間 { 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數(shù)據(jù) { 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) //將鏈表結(jié)點(diǎn)依次放入棧中 { 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; }
運(yùn)行程序可得如下結(jié)果:
《完》
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。