剑指offer面试题(6)——从尾到头打印链表

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

typedef struct Node
{
	int data;       //数据域
	struct Node * pNext;  //指针域
}*PNODE, NODE;

解题思路

        最直观的的做法是改变链表中链接节点的指针的指向,改变链表的方向,然后就可以遍历链表直接输出了。

      上述解题方法实现主要代码如下:

void inverse_list(PNODE pHead)
{
	cout << "反转链表方向输出结果:" << endl;
	if (pHead == nullptr || pHead->pNext == nullptr)
		return;
	PNODE pFront,p,temp; //pFront指向p的前一个节点
	if (pHead->pNext != nullptr)
	{
		pFront = pHead->pNext;
		if (pFront->pNext != nullptr)
		{
			p = pFront->pNext;
			while (p != nullptr)
			{
				//后移pFront,p指针
				temp = p->pNext;
				p->pNext = pFront;
				pFront = p;
				p = temp;
			}
			pHead->pNext->pNext = nullptr;
			pHead->pNext = pFront;
		}
	}
	traverse_list(pHead);//遍历链表
}

        但是这种解题方法会改变原链表的结构,因此在使用这种方法解题前要先确定是否能够改变输入的链表的结构。

        遍历链表的顺序是头到尾,而题目要求的输出顺序是从尾到头。即第一个遍历的节点最后一个输出,最后一个遍历的节点第一个输出,符合“后进先出”结构,因此可以通过栈来实现。这里为了方便,使用STL库的stack来实现。

        上述解题方法实现主要代码如下:

void inverse_traverse_list(PNODE pHead)
{
	cout << "压栈倒序输出结果:" << endl;
	if (pHead == nullptr || pHead->pNext == nullptr)
		return;
	std::stack<PNODE> nodes;
	PNODE p;
	p = pHead->pNext;
	while (p)
	{
		nodes.push(p);
		p = p->pNext;
	}
	int i = 0;
	while (!nodes.empty())
	{
		++i;
		p = nodes.top();
		cout << "第" << i << "个节点的数据为:" << p->data << endl;
		nodes.pop();
	}
}

        既然可以用栈来实现倒序输出,自然联想到可以使用递归来实现。因为递归本质上是栈结构。每访问一个节点,先递归输出它后面的节点,再输出该节点自身,这样就可以倒序输出了。

        上述解题方法实现主要代码如下:

void recursion_traverse_list(PNODE pHead)
{	
	if (pHead != nullptr)
	{
		if (pHead->pNext != nullptr)
			recursion_traverse_list(pHead->pNext);
		//创建链表时头结点的数据域初始化为NULL
		if(pHead->data != NULL)
			cout<< pHead->data <<endl;
	}
}

        可以用下面的创建链表和遍历链表函数来辅助测试三种倒序输出方法。

PNODE create_list()
{
	int i, len, value;
	PNODE pHead, pTail, pNew;
	pHead = new NODE();
	if (nullptr == pHead)
	{
		cout<<"内存分配失败,程序终止!";
		exit(-1);
	}
	pHead->data = NULL;
	pTail = pHead;
	pTail->pNext = nullptr;

	cout << "请输入需要的链表节点的个数 len = ";
	cin >> len;

	for (i = 0; i<len; i++)
	{
		pNew = new NODE();
		if (nullptr == pNew)
		{
			cout << "内存分配失败,程序终止!";
			exit(-1);
		}
		cout << "请输入需要填入第个" << i + 1 << "节点中的数据 :";
		cin >> value;
		pNew->data = value;
		pTail->pNext = pNew;
		pNew->pNext = nullptr;
		pTail = pNew;
	}
	return pHead;
}
void traverse_list(PNODE pHead)
{
	if (pHead == nullptr || pHead->pNext == nullptr)
		return;
	PNODE p;
	int i = 0;
	p = pHead->pNext;
	while (p)
	{
		++i;
		cout << "第" << i << "个节点的数据为:" << p->data << endl;
		p = p->pNext;
	}
}

测试用例1  

//空链表
int main(void)
{
	PNODE pHead = nullptr;
	//pHead = create_list();
	traverse_list(pHead);//遍历链表
	recursion_traverse_list(pHead);
	inverse_traverse_list(pHead);
	inverse_list(pHead);1
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/minghui_/article/details/80597275
今日推荐