从尾到头打印单向链表
需求:
給定一個(gè)單項(xiàng)鏈表的頭結(jié)點(diǎn),從尾到頭打印鏈表中的節(jié)點(diǎn)的值。
?
分析:
思路一
由于從鏈表的結(jié)尾開始逆序打印,也就是說最后的節(jié)點(diǎn)先打印,聯(lián)想到后進(jìn)先出,可以使用棧來依次把鏈表節(jié)點(diǎn)保存起來,然后從新棧頂開始獲取節(jié)點(diǎn)打印并且把節(jié)點(diǎn)出棧,直到棧為空,打印結(jié)束。見示例代碼reversePrintByStack。
?
思路二
由于打印的思想跟棧類似,可以進(jìn)一步聯(lián)想到函數(shù)調(diào)用保留現(xiàn)場(chǎng)也是通過棧的方式實(shí)現(xiàn)的,因此可以考慮使用遞歸來實(shí)現(xiàn),如果當(dāng)前節(jié)點(diǎn)后面還有節(jié)點(diǎn),則查找后面的節(jié)點(diǎn),等找到后面節(jié)點(diǎn)返回了,再打印當(dāng)前節(jié)點(diǎn)。如果當(dāng)前節(jié)點(diǎn)后面沒有節(jié)點(diǎn)了,就直接打印當(dāng)前節(jié)點(diǎn)的值。見示例代碼reversePrintByRecursion。
?
c++實(shí)例代碼
1 #include <iostream> 2 #include <stack> 3 4 using namespace std; 5 6 //單鏈表節(jié)點(diǎn) 7 struct ListNode { 8 //節(jié)點(diǎn)存儲(chǔ)的數(shù)字 9 int m_nValue; 10 //下一個(gè)節(jié)點(diǎn)的指針 11 ListNode* m_pNext; 12 }; 13 14 /************************************************************************/ 15 /* @brif 在鏈表結(jié)尾增加節(jié)點(diǎn) 16 /* @param pHead 鏈表頭結(jié)點(diǎn) 17 /* @param value 要增加的節(jié)點(diǎn)值 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 //頭結(jié)點(diǎn)為空的情況,新增加的節(jié)點(diǎn)作為頭結(jié)點(diǎn) 32 if (!*pHead) 33 { 34 *pHead = addNode; 35 } 36 //頭結(jié)點(diǎn)不為空的情況,查找到最后一個(gè)節(jié)點(diǎn),修改最后一個(gè)節(jié)點(diǎn)的指向 37 else 38 { 39 ListNode* tmpNode = *pHead; 40 //找到最后一個(gè)頭結(jié)點(diǎn) 41 while (tmpNode->m_pNext) 42 { 43 tmpNode = tmpNode->m_pNext; 44 } 45 tmpNode->m_pNext = addNode; 46 } 47 } 48 49 /************************************************************************/ 50 /* @brif 打印鏈表中的節(jié)點(diǎn) 51 /* @param pHead 鏈表頭結(jié)點(diǎn) 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 << "結(jié)束" << endl; 68 } 69 70 /************************************************************************/ 71 /* @brif 刪除鏈表中的所有節(jié)點(diǎn) 72 /* @param pHead 鏈表頭結(jié)點(diǎn) 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 鏈表頭結(jié)點(diǎn) 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 //依次把鏈表中的節(jié)點(diǎn)放到棧中 110 while (tmpNode->m_pNext) 111 { 112 listStack.push(tmpNode); 113 tmpNode = tmpNode->m_pNext; 114 } 115 //把最后一個(gè)節(jié)點(diǎn)也加入到棧中 116 listStack.push(tmpNode); 117 118 //如果棧不為空,則打印最上面的節(jié)點(diǎn),然后出棧 119 while (!listStack.empty()) 120 { 121 cout << (listStack.top())->m_nValue << "\t"; 122 listStack.pop(); 123 } 124 } 125 126 /************************************************************************/ 127 /* @brif 使用遞歸的方法逆序打印鏈表 128 /* @param pHead 鏈表頭結(jié)點(diǎn) 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 //創(chuàng)建鏈表 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 }?
運(yùn)行結(jié)果
?
轉(zhuǎn)載于:https://www.cnblogs.com/huangwenhao/p/11177314.html
總結(jié)
以上是生活随笔為你收集整理的从尾到头打印单向链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [Tips]Linux在命令行中打开图形
- 下一篇: 常考的js笔试语句