從尾到頭打印單向鏈表

需求:

給定一個單項鍊表的頭結點,從尾到頭打印鏈表中的節點的值。node

 

分析:

思路一

因爲從鏈表的結尾開始逆序打印,也就是說最後的節點先打印,聯想到後進先出,能夠使用棧來依次把鏈表節點保存起來,而後重新棧頂開始獲取節點打印而且把節點出棧,直到棧爲空,打印結束。見示例代碼reversePrintByStack。ios

 

思路二

因爲打印的思想跟棧相似,能夠進一步聯想到函數調用保留現場也是經過棧的方式實現的,所以能夠考慮使用遞歸來實現,若是當前節點後面還有節點,則查找後面的節點,等找到後面節點返回了,再打印當前節點。若是當前節點後面沒有節點了,就直接打印當前節點的值。見示例代碼reversePrintByRecursion。c++

 

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 }

 

運行結果

相關文章
相關標籤/搜索