面试题五:从尾到头打印链表|剑指offer

题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。(牛客网编程版)

与面试官确定题意:因为是从尾到头反过来打印每个结点,则要确定一下可不可以改变原来的链表结构?

下面,我将从改变链表结构和不改变链表结构来分析:

通常打印是一个只读操作,不希望修改打印的内容,所以我们先从不改变链表结构来分析 

从尾到头打印,跟栈的后进先出的模式有点相似,可以考虑使用栈来处理:

如下面代码所示,先遍历所有的结点,同时压入栈中,直到链表尾。最后从栈的顶端打印结点,弹出结点直到栈为空。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    void printListFromTailToHead(struct ListNode* head) {
        std::stack<ListNode *> nodes;
        ListNode* pNode = head;
        while(pNode != NULL){
            nodes.push(pNode);
            pNode = pNode->next;
        }
        while(!nodes.empty()){
            std::cout << nodes.top()->val;
            nodes.pop();
        }
    }
};
还有一种方法是使用递归的方法,因为递归本质上就是一个栈的结构。不过,在处理链表的时候,有一些出错问题需要考虑的,例如链表为空,当你需要用到结点的下一个结点的时候,就需要考虑只有一个元素应该怎样处理。

class Solution {
public:
	void printListFromTailToHead(struct ListNode* head) {
		if(head != NULL)
		{
			if (head->next != NULL)
			{
				printListFromTailToHead(head->next);
			}
			cout << head->val;
		}
	}
};


牛客网上的函数形式跟书本上不一样,它是返回一个vector<int>类数据,我们可以使用vector的库函数Insert来简化代码。开辟一个新的空间,然后调用vector容器的插值的方法,把链表的反向结构存放在容器里面。

/**
*  struct ListNode {
*        int val;
*        struct ListNode *next;
*        ListNode(int x) :
*              val(x), next(NULL) {
*        }
*  };
*/
class Solution {
public:
    vector<int> printListFromTailToHead(struct ListNode* head) {
        vector<int> temp;
        
        while(head != NULL){
            temp.insert(temp.begin(), head->val);
            head = head->next;
        }
        return temp;
        
    }
};


另外一种方法就是修改链表的结构,也就是先对链表进行反转,再遍历打印,可见博客:

链表反转






如上面代码所示,先遍历所有的结点,同时压入栈中,直到链表尾。最后从栈的顶端打印结点,弹出结点直到栈为空。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值