剑指offer面试题5



从尾到头打印链表

题目:输入一个链表的头节点,从未到头反过来打印出每个节点的值。

      链表结构如下:

      Struct  ListNode

      {

          Int  m_nkey;

          ListNode * m_pNext;

}

看到此题,我想很多人第一反应都会是将链表的节点指针反过来,改变链表的方向,这样就会很快打印出链表的每个节点的值,可是这样的方法改变了原有的链表结构,这种方法不太好,有局限性,如果面试官不让对链表的结构进行改变,那么这个方法就会被pass掉。

因此我们的思路如下:

  1. 可以定义一个数组来保存链表的每个节点的值,然后从后往前打印数组一遍,但是这样感觉需要很大的空间,很浪费空间

  2. 可以定义一个栈来存储数据,因为栈是先进后出,从头开始遍历节点,将节点按顺序进去,再按反序出来,刚好反序打印了一边链表。

  3. 因为递归的方法就是使用栈来实现的,我们还可以使用递归来实现此题,并且不需要定义一种数据结构来存储数据,直接可以打印出来。

解题方法如下:

  1. 先定义一个单链表,只需要实现初始化,插入就好。

  2. 在写一个递归打印单链表

代码如下:

#include<stdio.h>

#include<assert.h>

#include<stdlib.h>

 

typedef struct Node

{

    int data;//数据域

    struct Node *next;//指向下一个节点的地址

}Node ,*List;//List == Node *

 

 

//单链表以NULL结尾

void InitList(List plist)

{

    assert(plist != NULL);

    if(plist == NULL)

    {

       return;

    }

 

    plist->next = NULL;

}

 

List BuyNode(int val)

{

    Node *p = (Node *)malloc(sizeof(Node));

 

    p->data = val;

    //p->next = NULL;

 

    return p;

}

 

//头插

void Insert_Head(List plist ,int val) 

{

    Node *p = BuyNode(val);

   

    p->next = plist->next;//4

    plist->next = p;//3

}

 

 

//从头到尾打印链表

void Show(List plist)

{

    if(plist != NULL)

    {

       if(plist->next != NULL)

       {

           Show(plist->next);

       }

       printf("%d   \n",plist->data);

    }

}

 

 

int main()

{

    Node plist1;

    plist1.next=NULL;

    int i=0;

    for(i=0; i<10; i++)

    {

       Insert_Head(&plist1 ,i);

    }

    Show(&plist1);

    return 0;

}

 

运行结果如下:

猜你喜欢

转载自blog.csdn.net/YanJing1314/article/details/79433549