1. 程式人生 > >【100題】第五十八題 從尾到頭輸出連結串列

【100題】第五十八題 從尾到頭輸出連結串列

一,題目

        輸入一個連結串列的頭結點,從尾到頭反過來輸出每個結點的值。連結串列結點定義如下:
struct ListNode
{

      int       m_nKey;
      ListNode* m_pNext;
};

二,分析

       解法一:把連結串列中連結結點的指標反轉過來,改變連結串列的方向。然後就可以從頭到尾輸出了。參考

       解法二:從頭到尾遍歷連結串列,每經過一個結點的時候,把該結點放到一個棧中。當遍歷完整個連結串列後,再從棧頂開始輸出結點的值,此時輸出的結點的順序已經反轉過來了。該方法需要維護一個額外的棧,實現起來比較麻煩。

       解法三:遞迴本質上就是一個棧結構。於是很自然的又想到了用遞迴來實現。要實現反過來輸出連結串列,我們每訪問到一個結點的時候,先遞迴輸出它後面的結點,再輸出該結點自身,這樣連結串列的輸出結果就反過來了。

三,程式碼

基於這樣的思路,不難寫出如下程式碼:

void PrintListReversely(ListNode* pListHead)
{
      if(pListHead != NULL)
      {
            if (pListHead->m_pNext != NULL)
                  PrintListReversely(pListHead->m_pNext);
            else 
                  printf("%d", pListHead->m_nKey);
      }
}

擴充套件:該題還有兩個常見的變體:
       1.      
從尾到頭輸出一個字串;
       2.      
定義一個函式求字串的長度,要求該函式體內不能宣告任何變數。

#include <iostream>
using namespace std; 

void print(char *str)
{
		if(*(str+1)!='\0')
	    	 print(str+1);
    
         printf("%c ",str[0]); 	
}
 

int  getlength(char *str)
{
	if(*str=='\0')
		return 0;
	else
	    return getlength(str+1)+1; 
	
} 
int main()
{
	char *str="abcde"; 
	cout<<getlength(str)<<endl;
	
	print(str); 
}