題目:輸入一個鏈表的頭結點,從尾到頭反過來打印出每個節點的值
考察 單鏈表操作、棧、遞歸等概念。
理解:要實現單鏈表的輸出,那麼就需要遍歷。遍歷的順序是從頭到尾,而節點輸出的順序是從尾到頭。因此,先遍歷到的節點後輸出,這是一個典型的 “後進先出”。
要實現這樣的輸出,可以使用棧,或,遞歸。
通過這道題,讓我對 “遞歸在本質上就是一個棧結構” 理解的更加深刻。
代碼如下:
/************************************************************************/
/** 題目:輸入一個鏈表的頭結點,從尾到頭反過來打印出每個節點的值 */
/** 時間:2015.7.24 作者:jwt */
/************************************************************************/
#include <iostream>
#include <stack>
using namespace std;
typedef struct node{
int value;
struct node *next;
}Listnode;
/**創建一個單鏈表,n:表示節點數*/
Listnode * Create_List(int n)
{
int i = 0, elem;
Listnode *head, *temp, *curr;
head = new Listnode;
head->next = NULL;
head->value = n; /**頭結點保存數據節點個數*/
curr = head;
while(i < n) /*尾插法,新節點都放在最後*/
{
cout << "please input an elem: " << endl;
cin >> elem;
temp = new Listnode;
temp->value = elem;
temp->next = NULL;
curr->next = temp;
curr = temp;
i++;
}
return head;
}
/**棧實現反向輸出單鏈表*/
void Print_List_Reverse_with_stack(Listnode *head)
{
Listnode *p;
stack<int> temp;
if(NULL == head) /*頭結點爲空,那麼這個鏈表就不存在*/
return;
else{ /*鏈表的第一個數據節點是頭節點的下一個節點,因此鏈表爲空,就是第一個數據節點爲空*/
p = head->next;
if(NULL == p)
{
cout << "該鏈表爲空" << endl;
return;
}
}
do{
temp.push(p->value); /*遍歷到的節點數據依次入棧*/
p = p->next;
}while(NULL != p);
while(!temp.empty())
{
cout << temp.top() << ' '; /*輸出棧頂元素*/
temp.pop(); /*棧頂元素出棧*/
}
cout << endl;
}
/**遞歸實現反向輸出單鏈表*/
void Print(Listnode *head) /*遞歸函數*/
{
if(NULL != head)
{
if(NULL != head->next)
{
Print(head->next);
}
cout << head->value << ' ';
}
}
void Print_List_Reverse_Recursively(Listnode *head) /**加這一步的原因是防止輸出頭結點*/
{
if(NULL == head)
return;
Listnode *p;
p = head->next;
if(NULL == p)
{
cout << "鏈表爲空" << endl;
return;
}
else{
Print(p);
}
}
int main()
{
Listnode *test;
test = Create_List(5);
Print_List_Reverse_with_stack(test);
Print_List_Reverse_Recursively(test);
return 0;
}
結果如下:
/*點滴積累,我的一小步O(∩_∩)O~*/