題目:輸入一個鏈表的頭節點,從尾到頭反過來打印出每個節點的值。鏈表節點定義如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
首先,明確要解決這個問題肯定需要遍歷鏈表,但是遍歷鏈表的順序是從頭到尾,要求輸出的順序是從尾到頭。
思路一:第一個遍歷的節點最后一個輸出,最后一個遍歷的節點第一個輸出,典型的“后進先出”,可以用棧實現這個順序。每遍歷一個節點,放入棧中。當遍歷完所有節點后,再從棧頂開始輸出。
實現代碼:
void PrintList(ListNode* pHead)
{
std::stack<ListNode*>nodes; //定義棧
ListNode* pNode = pHead;
while(pNode!=nullptr)
{
nodes.push(pNode);
pNode = pNode->m_pNext;
}
while(!nodes.empty())
{
pNode = nodes.top();
printf("%d\t",pNode->m_nKey);
nodes.pop();
}
}
思路二:遞歸的本質是一個棧結構,可以采用遞歸思想。每訪問一個節點,先遞歸輸出其后面的節點,再輸出該節點自身,這樣就能夠實現鏈表的逆向輸出了。
void PrintList2(ListNode* pHead)
{
if(pHead !=nullptr)
{
if(pHead->m_pNext != nullptr)
{
PrintList2(pHead->m_pNext);
}
printf("%d\t",pHead->m_nKey);
}
}
思路二比較簡潔,但是當鏈表節點很多,鏈表很長,會導致過多的函數調用,層級很深,有可能導致函數調用棧溢出。顯然思路一基于循環實現的代碼的魯棒性要好一些。