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

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


解析:思路一:遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用栈实现这种顺序。

 

    每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。

代码实现 :

//利用栈:从尾到头打印链表
void PrintListReversing_Stack(ListNode* pHead)
{
	std::stack<ListNode*> node;

	ListNode* pNode = pHead;
	while (pNode!=NULL)
	{
		node.push(pNode);
		pNode = pNode->m_pNext;
	}

	while (!node.empty())
	{
		pNode = node.top();
		cout << pNode->m_nValue << "   ";
		node.pop();
	}
}


思路二:用递归实现

//递归法:从尾到头打印链表
void PrintListReversing_Recursive(ListNode* pHead)
{
	if (pHead != NULL)
	{
		if (pHead->m_pNext != NULL)
		{
			PrintListReversing_Recursive(pHead->m_pNext);
		}

		cout << pHead->m_nValue << "   ";
	}
}


      上面的基于递归的代码看起来很简洁,但是当链表非常长的时候,就会导致函数递归很深,从而有可能导致函数调用栈溢出。显然用栈基于循环实现的代码的鲁棒性要好一些。

 

测试用例:

// ====================测试代码==================== 
void Test(ListNode* pHead)
{
	PrintList(pHead);
	cout << "利用栈:";
	PrintListReversing_Stack(pHead);
	cout << endl << "递归法:";
	PrintListReversing_Recursive(pHead);
}


1.正常的多元素链表

void Test1()
{
	// 1->2->3->4->5
	cout << "Test1 begin:" << endl;

	ListNode* pNode1 = CreateListNode(1);
	ListNode* pNode2 = CreateListNode(2);
	ListNode* pNode3 = CreateListNode(3);
	ListNode* pNode4 = CreateListNode(4);
	ListNode* pNode5 = CreateListNode(5);

	ConnectListNodes(pNode1, pNode2);
	ConnectListNodes(pNode2, pNode3);
	ConnectListNodes(pNode3, pNode4);
	ConnectListNodes(pNode4, pNode5);

	Test(pNode1);
	cout << endl << "Test1 end." << endl;
	DestroyList(pNode1);
}


2.只有一个节点的链表

void Test2()
{
	// 只有一个结点的链表: 1
	cout << endl << "Test2 begin:" << endl;

	ListNode* pNode1 = CreateListNode(1);

	Test(pNode1);
	cout << endl << "Test2 end." << endl;
	DestroyList(pNode1);
}


3.鲁棒性测试:空链表

void Test3()
{
	// 空链表
	cout << endl << "Test3 begin:" << endl;

	Test(NULL);
	cout << endl << "Test3 end." << endl;
}

 

完整代码及其测试用例实现:

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

//链表节点定义
struct ListNode
{
	int m_nValue;
	ListNode* m_pNext;
};

//创建链表节点
ListNode* CreateListNode(int value)
{
	ListNode* pNode = new ListNode();
	pNode->m_nValue = value;
	pNode->m_pNext = NULL;

	return pNode;
}

// 链接链表节点
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
	if (pCurrent == NULL)
	{
		cout << "Error to connect two nodes." << endl;
		exit(1);
	}

	pCurrent->m_pNext = pNext;
}

//打印链表
void PrintList(ListNode* pHead)
{
	cout << "PrintList start:" << endl;

	ListNode* pNode = pHead;
	while (pNode!=NULL)
	{
		cout << pNode->m_nValue << "   ";
		pNode = pNode->m_pNext;
	}

	cout << endl << "PrintList end." << endl;
}

//销毁链表节点
void DestroyList(ListNode* pHead)
{
	ListNode* pNode = pHead;
	while (pNode != NULL)
	{
		pHead = pHead->m_pNext;
		delete pNode;
		pNode = pHead;
	}
}

//利用栈:从尾到头打印链表
void PrintListReversing_Stack(ListNode* pHead)
{
	std::stack<ListNode*> node;

	ListNode* pNode = pHead;
	while (pNode!=NULL)
	{
		node.push(pNode);
		pNode = pNode->m_pNext;
	}

	while (!node.empty())
	{
		pNode = node.top();
		cout << pNode->m_nValue << "   ";
		node.pop();
	}
}

//递归法:从尾到头打印链表
void PrintListReversing_Recursive(ListNode* pHead)
{
	if (pHead != NULL)
	{
		if (pHead->m_pNext != NULL)
		{
			PrintListReversing_Recursive(pHead->m_pNext);
		}

		cout << pHead->m_nValue << "   ";
	}
}

// ====================测试代码==================== 
void Test(ListNode* pHead)
{
	PrintList(pHead);
	cout << "利用栈:";
	PrintListReversing_Stack(pHead);
	cout << endl << "递归法:";
	PrintListReversing_Recursive(pHead);
}

void Test1()
{
	// 1->2->3->4->5
	cout << "Test1 begin:" << endl;

	ListNode* pNode1 = CreateListNode(1);
	ListNode* pNode2 = CreateListNode(2);
	ListNode* pNode3 = CreateListNode(3);
	ListNode* pNode4 = CreateListNode(4);
	ListNode* pNode5 = CreateListNode(5);

	ConnectListNodes(pNode1, pNode2);
	ConnectListNodes(pNode2, pNode3);
	ConnectListNodes(pNode3, pNode4);
	ConnectListNodes(pNode4, pNode5);

	Test(pNode1);
	cout << endl << "Test1 end." << endl;
	DestroyList(pNode1);
}

void Test2()
{
	// 只有一个结点的链表: 1
	cout << endl << "Test2 begin:" << endl;

	ListNode* pNode1 = CreateListNode(1);

	Test(pNode1);
	cout << endl << "Test2 end." << endl;
	DestroyList(pNode1);
}

void Test3()
{
	// 空链表
	cout << endl << "Test3 begin:" << endl;

	Test(NULL);
	cout << endl << "Test3 end." << endl;
}

int main()
{
	Test1();
	Test2();
	Test3();

	system("pause");
	return 0;
}


运行结果:

Test1 begin:

PrintList start:

1   2   3   4   5

PrintList end.

利用栈:5   4   3   2   1

递归法:5   4   3   2   1

Test1 end.

 

Test2 begin:

PrintList start:

1

PrintList end.

利用栈:1

递归法:1

Test2 end.

 

Test3 begin:

PrintList start:

 

PrintList end.

利用栈:

递归法:

Test3 end.

请按任意键继续. . .

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值