二叉搜索树转化为双向链表

1. 题目

输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现。

二叉树结点的定义如下:

struct BinaryTreeNode

{

      intm_nValue;

      BinaryTreeNode*m_pLeft;

      BinaryTreeNode*m_pRight;

};

如图1-1(a)为一棵二叉搜索树,1-1(b)为对应的双向链表。

图1-1转化示意图

2. 分析

(1) 二叉搜索树中序遍历可得有序的结点序列。图1-1(a)对应的中序序列{4,6,8,10,12,14,16}。

(2) 双向链表中的结点是有序的。如图1-1(b)链表遍历序列为{4,6,8,10,12,14,16}。

由(1)与(2)可得,双向链表求解过程可类比于二叉搜索树的中序遍历操作。中序遍历访问结点时,将该结点插入到双向链表的链尾。因此,递归实现过程中需要两个参数:当前子树的根结点与当前链表的尾指针。在函数调用中需要改变尾指针指向新的子树根结点而并非其指向地址的数据,因此需要使用指针的引用。

3. 测试代码

测试样例:按照先序顺序输入二叉搜索树,当结点没有左孩子时输入-1表示该孩子结点不存在,每数字之间用空格分开。例图1-1(a)的输入方式为:10 64 -1 -1 8 -1 -1 14 12 -1 -1 16 -1 -1。

#include <iostream>
using namespace std;

struct BinaryTreeNode
{
	int m_nValue;
	BinaryTreeNode* m_pLeft;
	BinaryTreeNode* m_pRight;
};

void PrintList(BinaryTreeNode *pRoot)
{
	//顺序打印链表
	while (pRoot != NULL)
	{
		cout << pRoot->m_nValue << " ";
		pRoot = pRoot->m_pRight;
	}
}

void PrintTree(BinaryTreeNode *pRoot)
{
	//中序打印二叉树
	if (pRoot == NULL)
	{
		return;
	}
	if (pRoot->m_pLeft != NULL)
	{
		PrintTree(pRoot->m_pLeft);
	}
	cout << pRoot->m_nValue << " ";
	if (pRoot->m_pRight != NULL)
	{
		PrintTree(pRoot->m_pRight);
	}
}

void CreatTree(BinaryTreeNode *&pRoot)//必须为指针引用        
{        
	//先序顺序输入一棵搜索树
	int newData;
	cin >> newData;  
	if (-1 == newData)
	{        
		pRoot = NULL;  
	}        
	else
	{        
		pRoot = new BinaryTreeNode;
		pRoot->m_nValue = newData;
		CreatTree(pRoot->m_pLeft);
		CreatTree(pRoot->m_pRight);
	}        
}

void Convert(BinaryTreeNode *pRoot, BinaryTreeNode *&pTail)//一定要定义为指针的引用,否则无法改变其指向的地址
{
	if (pRoot == NULL)
	{
		return;
	}
	//类似于访问左子树
	if (pRoot->m_pLeft != NULL)
	{
		Convert(pRoot->m_pLeft, pTail);
	}
	//类似于访问当前节点
	pRoot->m_pLeft = pTail;
	if (pTail != NULL)
	{
		pTail->m_pRight = pRoot;
	}
	//若不是引用,函数运行结束,下面赋值无效
	pTail = pRoot;
	//类似于访问右子树
	if (pRoot->m_pRight != NULL)
	{
		Convert(pRoot->m_pRight, pTail);
	}
}

BinaryTreeNode *Convert(BinaryTreeNode *pRoot)
{
	BinaryTreeNode *pHead = NULL;
	BinaryTreeNode *pTail = NULL;
	Convert(pRoot, pTail);
	pHead = pTail;
	while (pHead != NULL && pHead->m_pLeft != NULL)
	{
		pHead = pHead->m_pLeft;
	}
	return pHead;
}



int main()
{
	BinaryTreeNode* pRoot = NULL;
	BinaryTreeNode* pHead = NULL;

	CreatTree(pRoot);
	cout << "树的中序遍历:" << endl;
	PrintTree(pRoot);
	cout << endl;

	pHead = Convert(pRoot);
	PrintList(pHead);
	system("pause");
	return 1;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值