剑指Offer----面试题五:从尾到头打印链表

转载请注明出处<http://blog.csdn.net/qianqin_2014/article/details/51457485>


前述:

链表的创建、结点的插入、结点的删除等操作都只需要20行左右的代码就能实现,其代码量比较适合面试。

链表问题:面试题5“从尾到头输出链表”、面试题13“在O(1)时间删除链表结点”、面试题15“链表中的倒数第k个结点”、面试题16“反转链表”、面试题17“合并两个排序的链表”、面试题37“两个链表的第一个公共结点”、面试题45“圆圈中最后剩下的数字”、面试题27“二叉搜索树与双向链表”、面试题26“复杂链表的赋值”。

题目:

输入一个链表的头结点,从尾到头反过来点每个结点的值。

提示:面试中如果打算修改输入的数据,最好先问面试官是不是允许做修改。

思路一:

遍历的顺序是从头到尾,可是却要从尾到头打印,符合“后进先出”栈的规律。

源代码:
void printReversingly_Iteratively(ListNode *pHead)
	{
		
		if (pHead == NULL)
		{
			std::cout << "The list is empty" << std::endl;
			return;
		}
		else
		{
			std::stack<ListNode *> st;
			ListNode * pNew = pHead;
			while (pNew != NULL)
			{
				st.push(pNew);
				pNew = pNew->next;
			}

			while (!st.empty())
			{
				std::cout << st.top()->element << "  ";
				st.pop();
			}
		}
	}

思路二:


既然想到用栈来实现这个函数,而递归的本质就是一个栈结构,所以本函数也可以用递归来解决。

源代码:
void printReversingly_Recursively(ListNode *pHead)
	{
		if (pHead != NULL)
		{
			if (pHead->next != NULL)
				printReversingly_Recursively(pHead->next);
			std::cout << pHead->element << "  ";
		}
	}

注意:当链表非常长的时候,就会导致函数调用的层级很深,从而有可能导致函数调用栈溢出。

官方源代码(经过修改):


头文件List.h

#ifndef LIST_NODE_H
#define LIST_NODE_H

namespace ListSpace
{

	struct ListNode
	{
		int element;
		ListNode *next;
	};

	ListNode * CreateListNode(int valude);
	void ConnectListNodes(ListNode *pCurrent, ListNode *pNext);
	void printListNode(ListNode *pHead);
	void printList(ListNode *pHead);
	void printReversingly_Iteratively(ListNode *pHead);
	void printReversingly_Recursively(ListNode *pHead);
	void DestoryList(ListNode **pHead);
	void AddToTail(ListNode ** pHead, int value);
	void RemoveNode(ListNode ** pHead, int value);
	
}

#endif

源文件List.cpp

#include"List.h"
#include<iostream>
#include<stack>

namespace ListSpace
{
	ListNode * CreateListNode(int value)
	{
		ListNode *pNew = new ListNode();
		pNew->element = value;
		pNew->next = NULL;

		return pNew;
	}

	void ConnectListNodes(ListNode *pCurrent, ListNode *pNext)
	{
		if (pCurrent == NULL)
			std::cout << "Linking Error..." << std::endl;
		else
		{
			pCurrent->next = pNext;
		}
	}

	void printListNode(ListNode *pHead)
	{
		if (pHead == NULL)
			std::cout << "The value of this node is empty" << std::endl;
		else
			std::cout << "The value of this node is " << pHead->element << std::endl;
	}

	void printList(ListNode *pHead)
	{
		if (pHead == NULL)
			std::cout << "The list is empty" << std::endl;
		else
		{
			ListNode *pNew = pHead;
			while (pNew != NULL)
			{
				std::cout << pNew->element << "  ";
				pNew = pNew->next;
			}
		}
	}

	void printReversingly_Iteratively(ListNode *pHead)
	{
		
		if (pHead == NULL)
		{
			std::cout << "The list is empty" << std::endl;
			return;
		}
		else
		{
			std::stack<ListNode *> st;
			ListNode * pNew = pHead;
			while (pNew != NULL)
			{
				st.push(pNew);
				pNew = pNew->next;
			}

			while (!st.empty())
			{
				std::cout << st.top()->element << "  ";
				st.pop();
			}
		}
	}

	void printReversingly_Recursively(ListNode *pHead)
	{
		if (pHead != NULL)
		{
			if (pHead->next != NULL)
				printReversingly_Recursively(pHead->next);
			std::cout << pHead->element << "  ";
		}
	}

	void DestoryList(ListNode **pHead)
	{
		ListNode *pNew = *pHead;
		while (pNew != NULL)
		{
			*pHead = (*pHead)->next;
			delete pNew;
			pNew = *pHead;
		}
	}

	void AddToTail(ListNode ** pHead, int value)
	{
		ListNode *pNew = new ListNode();
		pNew->element = value;
		pNew->next = NULL;

		if (*pHead == NULL)
			*pHead = pNew;
		else
		{
			//找到最后一个结点
			ListNode *node = *pHead;
			while (node ->next != NULL)
				node = node->next;

			node->next = pNew;
		}
	}

	void RemoveNode(ListNode ** pHead, int value)
	{
		if (pHead == NULL || *pHead == NULL)
			return;
		
		ListNode *pToBeDeleted = NULL;
		if ((*pHead)->element == value)
		{
			pToBeDeleted = *pHead;
			*pHead = (*pHead)->next;
		}
		else
		{
			ListNode *node = *pHead;
			while (node->next != NULL && node->next->element != value)
				node = node->next;
			if (node->next != NULL && node->next->element == value)
			{
				pToBeDeleted = node->next;
				node->next = node->next->next;
			}
		}

		if (pToBeDeleted != NULL)
		{
			delete pToBeDeleted;
			pToBeDeleted = NULL;
		}
	}
}

测试文件

#include"List.h"
#include<iostream>

using namespace ListSpace;

void Test(ListNode* pHead)
{
	printList(pHead);
	printReversingly_Recursively(pHead);
	printf("\n");
	printReversingly_Recursively(pHead);
}

// 1->2->3->4->5
void Test1()
{
	printf("\nTest1 begins.\n");

	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);

	DestoryList(&pNode1);
}

// 只有一个结点的链表: 1
void Test2()
{
	printf("\nTest2 begins.\n");

	ListNode* pNode1 = CreateListNode(1);

	Test(pNode1);

	DestoryList(&pNode1);
}

// 空链表
void Test3()
{
	printf("\nTest3 begins.\n");

	Test(NULL);
}

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

	system("pause");
	return 0;
}

运行结果:
Test1 begins.
1  2  3  4  5  5  4  3  2  1
5  4  3  2  1
Test2 begins.
1  1
1
Test3 begins.
The list is empty

请按任意键继续. . .

转载请注明出处<http://blog.csdn.net/qianqin_2014/article/details/51457485>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值