給定一個單項鍊表的頭結點,從尾到頭打印鏈表中的節點的值。node
因爲從鏈表的結尾開始逆序打印,也就是說最後的節點先打印,聯想到後進先出,能夠使用棧來依次把鏈表節點保存起來,而後重新棧頂開始獲取節點打印而且把節點出棧,直到棧爲空,打印結束。見示例代碼reversePrintByStack。ios
因爲打印的思想跟棧相似,能夠進一步聯想到函數調用保留現場也是經過棧的方式實現的,所以能夠考慮使用遞歸來實現,若是當前節點後面還有節點,則查找後面的節點,等找到後面節點返回了,再打印當前節點。若是當前節點後面沒有節點了,就直接打印當前節點的值。見示例代碼reversePrintByRecursion。c++
1 #include <iostream> 2 #include <stack> 3 4 using namespace std; 5 6 //單鏈表節點 7 struct ListNode { 8 //節點存儲的數字 9 int m_nValue; 10 //下一個節點的指針 11 ListNode* m_pNext; 12 }; 13 14 /************************************************************************/ 15 /* @brif 在鏈表結尾增長節點 16 /* @param pHead 鏈表頭結點 17 /* @param value 要增長的節點值 18 /************************************************************************/ 19 void AddNodeToTail(ListNode** pHead, int value) 20 { 21 ListNode *addNode = new ListNode; 22 23 if (!addNode) 24 { 25 cout << "add node fail!!!" << endl; 26 return; 27 } 28 addNode->m_nValue = value; 29 addNode->m_pNext = nullptr; 30 31 //頭結點爲空的狀況,新增長的節點做爲頭結點 32 if (!*pHead) 33 { 34 *pHead = addNode; 35 } 36 //頭結點不爲空的狀況,查找到最後一個節點,修改最後一個節點的指向 37 else 38 { 39 ListNode* tmpNode = *pHead; 40 //找到最後一個頭結點 41 while (tmpNode->m_pNext) 42 { 43 tmpNode = tmpNode->m_pNext; 44 } 45 tmpNode->m_pNext = addNode; 46 } 47 } 48 49 /************************************************************************/ 50 /* @brif 打印鏈表中的節點 51 /* @param pHead 鏈表頭結點 52 /************************************************************************/ 53 void printLinkList(ListNode* pHead) 54 { 55 ListNode* currNode = pHead; 56 57 if (!currNode) 58 { 59 cout << "空鏈表" << endl; 60 } 61 62 while (currNode) 63 { 64 cout << currNode->m_nValue << "->"; 65 currNode = currNode->m_pNext; 66 } 67 cout << "結束" << endl; 68 } 69 70 /************************************************************************/ 71 /* @brif 刪除鏈表中的全部節點 72 /* @param pHead 鏈表頭結點 73 /************************************************************************/ 74 void removeAllNode(ListNode** pHead) 75 { 76 ListNode* currNode = *pHead; 77 78 if (!*pHead) 79 { 80 cout << "空鏈表" << endl; 81 } 82 83 ListNode* delNode = nullptr; 84 while ((*pHead)->m_pNext) 85 { 86 delNode = (*pHead); 87 (*pHead) = (*pHead)->m_pNext; 88 delete delNode; 89 delNode = nullptr; 90 } 91 delete (*pHead); 92 *pHead = nullptr; 93 } 94 95 /************************************************************************/ 96 /* @brif 使用棧逆序打印鏈表 97 /* @param pHead 鏈表頭結點 98 /************************************************************************/ 99 void reversePrintByStack(ListNode* pHead) 100 { 101 if (!pHead) 102 { 103 cout << "空鏈表" << endl; 104 } 105 106 stack<ListNode*> listStack; 107 ListNode* tmpNode = pHead; 108 109 //依次把鏈表中的節點放到棧中 110 while (tmpNode->m_pNext) 111 { 112 listStack.push(tmpNode); 113 tmpNode = tmpNode->m_pNext; 114 } 115 //把最後一個節點也加入到棧中 116 listStack.push(tmpNode); 117 118 //若是棧不爲空,則打印最上面的節點,而後出棧 119 while (!listStack.empty()) 120 { 121 cout << (listStack.top())->m_nValue << "\t"; 122 listStack.pop(); 123 } 124 } 125 126 /************************************************************************/ 127 /* @brif 使用遞歸的方法逆序打印鏈表 128 /* @param pHead 鏈表頭結點 129 /************************************************************************/ 130 void reversePrintByRecursion(ListNode* pHead) 131 { 132 if (!pHead) 133 { 134 cout << "空鏈表" << endl; 135 } 136 137 if (pHead->m_pNext) 138 { 139 reversePrintByRecursion(pHead->m_pNext); 140 cout << pHead->m_nValue << "\t"; 141 } 142 else 143 { 144 cout << pHead->m_nValue << "\t"; 145 } 146 } 147 148 int main() 149 { 150 ListNode* pHead = nullptr; 151 152 cout << "原始鏈表:" << endl; 153 //建立鏈表 154 for (int i = 1; i <= 10; ++i) 155 { 156 AddNodeToTail(&pHead, i); 157 } 158 printLinkList(pHead); 159 160 cout << endl <<"經過棧逆序打印鏈表:" << endl; 161 reversePrintByStack(pHead); 162 163 cout << endl << "經過遞歸的方法逆序打印鏈表" << endl; 164 reversePrintByRecursion(pHead); 165 166 removeAllNode(&pHead); 167 168 cout << endl; 169 170 return 0; 171 }