从尾到头打印链表
题目:输入一个链表的头节点,从未到头反过来打印出每个节点的值。
链表结构如下:
Struct ListNode
{
Int m_nkey;
ListNode * m_pNext;
}
看到此题,我想很多人第一反应都会是将链表的节点指针反过来,改变链表的方向,这样就会很快打印出链表的每个节点的值,可是这样的方法改变了原有的链表结构,这种方法不太好,有局限性,如果面试官不让对链表的结构进行改变,那么这个方法就会被pass掉。
因此我们的思路如下:
-
可以定义一个数组来保存链表的每个节点的值,然后从后往前打印数组一遍,但是这样感觉需要很大的空间,很浪费空间
-
可以定义一个栈来存储数据,因为栈是先进后出,从头开始遍历节点,将节点按顺序进去,再按反序出来,刚好反序打印了一边链表。
-
因为递归的方法就是使用栈来实现的,我们还可以使用递归来实现此题,并且不需要定义一种数据结构来存储数据,直接可以打印出来。
解题方法如下:
-
先定义一个单链表,只需要实现初始化,插入就好。
-
在写一个递归打印单链表
代码如下:
#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;
}
运行结果如下: