逆向打印单向链表的所有结点

一、题目描述:
       输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
         链表结点定义如下:
         struct  ListNode
         {
                int             m_nKey;
                ListNode  *m_pNext;
         };

二、解决思路:
       单链表的特性是每个结点只有指向它的下一个结点指针;
       所以我们遍历输出时只能正向遍历,而正向遍历又想获得逆向输出,我们很自然的就想到了递归。确实递归是一种解决该问题的一种思路:

void ReversePrintList(ListNode *Head)
{
	if(Head != NULL)
	{
		ReversePrintList(Head->m_pNext);
		printf("%d, ", Head->m_nKey);
	}
}

       递归的代码看起来很简洁,但存在一个问题:当链表非常长的时候,就会导致函数调用层级很深,从而有可能导致函数调用栈溢出,这是一个很致命的问题!
      
       递归导致栈溢出的问题,我们通常使用栈来解决!

       我们使用栈来对链表逆序输出:首先遍历一次链表将结点放入一个栈中,然后遍历栈。:

void ReversePrintListByStack(ListNode *Head)
{
	stack<ListNode *> myStack;
	ListNode *temp;
	while(Head != NULL)
	{
		myStack.push(Head);
		Head = Head->m_pNext;
	}

	while(!myStack.empty())
	{
		temp = myStack.top();
		printf("%d, ", temp->m_nKey);
		myStack.pop();
	}

	printf("\n\n");
}


三、源代码:

#include <iostream>
#include <stack>
using namespace std;

struct ListNode
{
	int			m_nKey;
	ListNode	*m_pNext;
};

//头插元素
void HeadInsert(ListNode **Head, int key)
{
	ListNode *pNewNode = new ListNode;
	if(pNewNode == NULL)
	{
		return;
	}
	pNewNode->m_nKey = key;
	pNewNode->m_pNext = *Head;
	*Head = pNewNode;
}

//正向输出
void PrintList(ListNode *Head)
{
	while(Head != NULL)
	{
		printf("%d, ", Head->m_nKey);
		Head = Head->m_pNext;
	}
	printf("\n\n");
}

//递归法逆向输出
void ReversePrintList(ListNode *Head)
{
	if(Head != NULL)
	{
		ReversePrintList(Head->m_pNext);
		printf("%d, ", Head->m_nKey);
	}
}

//栈方法逆向输出
void ReversePrintListByStack(ListNode *Head)
{
	stack<ListNode *> myStack;
	ListNode *temp;
	while(Head != NULL)
	{
		myStack.push(Head);
		Head = Head->m_pNext;
	}

	while(!myStack.empty())
	{
		temp = myStack.top();
		printf("%d, ", temp->m_nKey);
		myStack.pop();
	}

	printf("\n\n");
}


int main(void)
{
	ListNode *Head = NULL;

	for(int i = 0; i < 10; i++)
	{
		HeadInsert(&Head, i);
	}

	printf("正向输出结果: \n");
	PrintList(Head);

	printf("递归法逆向输出结果: \n");
	ReversePrintList(Head);
	printf("\n\n");
	printf("栈方法逆向输出结果: \n");
	ReversePrintListByStack(Head);
	return 0;
}

四、运行截图:

                       

文章内容源自剑指Offer!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值