题目描述
输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
题解思路
方法一:栈
解决这个问题肯定要遍历链表。遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。
这就是典型的“后进先出”,我们可以用栈实现这种顺序。
每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。
代码实现:
void PrintListReversing(ListNode* Head){
stack<ListNode *> s;
ListNode * pnode = Head;
while(pnode != NULL){
s.push(pnode);
pnode = pnode->m_next;
}
while(!s.empty()){
pnode = s.top();
s.pop();
cout << pnode->m_value << "->";
}
}
方法二:递归
既然是用栈结构来实现这个函数,而递归在本质上就是一个栈结构,自然也就可以用栈来实现。
每访问一个节点的时候,先递归输出它后面的节点,再输出该节点自身。
代码实现:
void PrintListReversing(ListNode* Head){
if(Head){
if(Head->m_next != NULL){
PrintListReversing(Head->m_next);
}
cout << Head->m_value << "->";
}
}
两种方法的对比:上面的基于递归的代码看起来很简洁,但有个问题:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。用栈基于循环实现的代码的鲁棒性要好一些。
方法三:辅助数组
代码实现:
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) :
* val(x), next(NULL) {
* }
* };
*/
class Solution {
public:
vector<int> printListFromTailToHead(ListNode* head) {
vector<int> v;
if(!head) return v;
while(head){
int tmp = head->val;
v.push_back(tmp);
head = head->next;
}
reverse(v.begin(), v.end());
return v;
}
};
实现链表
#include <iostream>
#include <stack>
using namespace std;
typedef struct ListNode{
int m_value;
struct ListNode * m_next;
}ListNode;
// 从尾到头打印链表
void PrintListReversing_1(ListNode* Head){
stack<ListNode *> s;
ListNode * pnode = Head;
while(pnode != NULL){
s.push(pnode);
pnode = pnode->m_next;
}
while(!s.empty()){
pnode = s.top();
s.pop();
cout << pnode->m_value << "->";
}
cout << "NULL" << endl;
}
void PrintListReversing(ListNode* Head){
if(Head){
if(Head->m_next != NULL){
PrintListReversing(Head->m_next);
}
cout << Head->m_value << "->";
}
}
void Insert(ListNode * head, int val){
ListNode * temp = new ListNode;
temp->m_value = val;
#if 1
// 头插
temp->m_next = head->m_next;
head->m_next = temp;
#else
// 尾插
ListNode * p = head;
while(p->m_next != NULL){
p = p->m_next;
}
p->m_next = temp;
temp->m_next = NULL;
#endif
}
void Print(ListNode * head){
ListNode * temp = head->m_next;
while(temp){
cout << temp->m_value << "->";
temp = temp->m_next;
}
cout << "NULL" << endl;
}
void Free(ListNode * head){
ListNode * p = head;
ListNode * temp;
while(p){
temp = p->m_next;
delete temp;
p = temp;
}
}
ListNode *init(){
ListNode * temp = new ListNode;
temp->m_next = NULL;
return temp;
}
int main(){
ListNode * Head = init();
for(int i = 1; i < 10; ++i){
Insert(Head, i);
}
Print(Head);
PrintListReversing(Head->m_next);
cout << "NULL" << endl;
PrintListReversing_1(Head->m_next);
Free(Head);
return 0;
}
代码生成图:
如有不同见解,欢迎留言讨论~~~