代码改变世界

面试题8:从尾到头打印单链表

2016-03-28 22:30  Keiven_LY  阅读(1324)  评论(0编辑  收藏  举报

题目描述:

实现一个函数,输入一个单链表的头结点,从尾到头反过来打印出每个结点的值

思路1第一反应是将链表中的指针反转,改变链表的方向,然后再从头打印出来(该方法改变了原来链表的结构,这就要看面试或笔试时的要求,可否改变链表结构)

思路2遍历链表时是从头到尾,而打印链表时却是从尾到头,典型的“先进后出”——栈的特点,从而可以用栈来实现。每遍历一个节点,把该节点放到一个栈中,当遍历完整个链表后,再从栈顶开始逐个输出节点的值,此时输出的节点顺序已经反转过来了。

思路3栈可以实现,而递归本质上也是一个栈结构,从而可以用递归来实现。即:没遍历到一个节点时,先递归输出其后面的一个节点的值,再输出该节点本身的值。

方法一:采用思路1(见上篇  面试题7:单链表的反转/逆序

方法二:采用栈来实现

功能函数:

/*     用栈实现从尾到头打印单链表    */
void ReversePrintLinkListbystack(Node *head)
{
    Node *p = head->next;
    stack<int> s;
    while(head != NULL && p != NULL)   //入栈
    {
        s.push(p->data);
        p = p->next;
    }

    while(! s.empty())  //出栈
    {
        cout << s.top() << " ";
        s.pop();
    }
    cout << endl;
}

方法三:采用递归实现

功能函数:

/*     用递归实现从尾到头打印单链表    */
void ReversePrintLinkListbyRecursionk(Node *head)
{
    Node *p;

    if(head==NULL || head->next==NULL)
        return;
    else
    {
        p=head->next;
        ReversePrintLinkListbyRecursionk(p); 
        cout << p->data <<" ";       
    }
}

完整可执行程序如下:

#include<iostream>
#include <stack>
#include<stdlib.h> 
#include<time.h>

using namespace std;

typedef struct node
{
    int data;
    struct node *next;
}Node;

/*     创建含有n个结点的单链表    */
Node *CreateListHead(int n) 
{
    Node *head;
    head=(Node *)malloc(sizeof(Node)); /*创建头结点*/
    Node *q = head;

    /* 初始化随机数种子 */
    srand(time(0));  //srand函数在stdlib.h头文件中,time函数在time.h头文件中

    for(int i=0; i < n; i++)
    {
        Node *p = (Node *)malloc(sizeof(Node));
        p->data = rand()%100+1;  //随机生成100以内的数字 
        p->next = q->next;
        q->next = p;
        q = p;
    }
    q->next = NULL;

    return head;
}
/*     用栈实现从尾到头打印单链表    */
void ReversePrintLinkListbystack(Node *head)
{
    Node *p = head->next;
    stack<int> s;
    while(head != NULL && p != NULL)   //入栈
    {
        s.push(p->data);
        p = p->next;
    }

    while(! s.empty())  //出栈
    {
        cout << s.top() << " ";
        s.pop();
    }

    cout << endl;
}

/*     用递归实现从尾到头打印单链表    */
void ReversePrintLinkListbyRecursionk(Node *head)
{
    Node *p;

    if(head==NULL || head->next==NULL)
        return;
    else
    {
        p=head->next;
        ReversePrintLinkListbyRecursionk(p); 
        cout << p->data <<" ";       
    }
}

/****打印单链表******/
void print(Node *head)
{
    Node *p;
    if(head->next==NULL)
    {
        cout << "The LinkList is Empty !" <<endl;
        return;
    }
    p=head->next;
    while(p!=NULL)
    {
        cout << p->data << " " ;
        p=p->next;
    }
}
int main()
{
    Node *SingleLinkList = NULL;
    int length;

    cout << "Please input the length of LinkList: ";
    cin >> length;
    SingleLinkList = CreateListHead(length);
    cout << "The new created LinkList as below: " ;
    print(SingleLinkList);
    cout << endl;

    cout << "Reverse Print LinkList by Recursion: " ;
    ReversePrintLinkListbyRecursionk(SingleLinkList);
    cout << endl;

    cout << "Reverse Print LinkList by stack: " ;
    ReversePrintLinkListbystack(SingleLinkList);

    system("pause");
    return 0;
}

运行结果: