题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值。
解析:思路一:遍历的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点第一个输出。这就是典型的“后进先出”,我们可以用栈实现这种顺序。
每经过一个结点的时候,把该结点放到一个栈中。当遍历完整个链表后,再从栈顶开始逐个输出结点的值,此时输出的结点的顺序已经反转过来了。
代码实现 :
//利用栈:从尾到头打印链表
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.
请按任意键继续. . .