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

来源:互联网 发布:幼儿园区域阅美工图片 编辑:程序博客网 时间:2024/06/06 19:52

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

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

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

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

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

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

/***  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;            }};


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

链表反转






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