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

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;
}
时间: 2024-08-24 22:17:57

二叉搜索树转化为双向链表的相关文章

4.二叉搜索树转为有序双向链表(递归算法与非递归算法)

一.题目 要求输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建新的节点,只能调整树中结点指针的指向. 二叉树结点定义如下: 1 struct BinaryTreeNode 2 { 3 int m_nValue; 4 BinaryTreeNode *m_pLeft; 5 BinaryTreeNode *m_pRight; 6 }; 图1.二叉搜索树转为有序双向链表 二.算法 (1)递归算法 因为二叉搜索树每个结点的子树也是一棵二叉搜索树,所以,我们可以把问题分解为, 把左子

二叉搜索树转换为有序双向链表

http://blog.csdn.net/ljianhui/article/details/22338405 一.问题描述 输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表.而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现. 二.实现思路 在二叉搜索树中,每个结点都有两个分别指向其左.右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值.而在双向链表中,每个结点也有两个指针,它们分别指向前一个结点和后一个结点.所以这两种数据

二叉搜索树变成有序双向链表,要求不能创建新的结点,只调整指针的指向

二叉搜索树的结点有2个指针,分别指向左右孩子,双链表的每个结点也有2个指针,分别指向前后结点,所以在不创建新结点,只调整指针指向时可以将二叉搜索树变成双向链表:又由于二叉搜索树在中序遍历时是有序的,所以可以采用中序处理二叉搜索树调整指针指向将其变成有序双向链表.为了简化指针移动操作,我们让左孩子为前向指针,右孩子为后向指针. 二叉搜索树的最左结点即使整个树中最小的结点,所以首先找到最左结点,它就是链表的首结点,链表最后一个结点初始化为空.中序遍历时,当前结点的左孩子指向链表的最后一个结点,若最后

九:二叉搜索树与双向链表(二叉搜索树转为有序双向链表)

问题描述: 输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表.而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现. 解析: 借助二叉树中序遍历,因为中序遍历二叉搜索树的特点就是从小到大访问结点.当遍历访问到根结点时,假设根结点的左侧已经处理好,只需将根结点与上次访问的最近结点(左子树中最大值结点)的指针连接好即可.进而更新当前链表的最后一个结点指针. 递归算法: (1)中序遍历. (2)原先指向左子结点的指针调整为链表中指向前一个结点的指针,原先指向右子

把二叉搜索树转化成更大的树 &#183; Convert BST to Greater Tree

[抄题]: 给定二叉搜索树(BST),将其转换为更大的树,使原始BST上每个节点的值都更改为在原始树中大于等于该节点值的节点值之和(包括该节点). Given a binary search Tree `{5,2,13}`: 5 / 2 13 Return the root of new tree 18 / 20 13 [暴力解法]: 时间分析: 空间分析: [思维问题]: [一句话思路]: 反向求和并把和赋给root.val [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常

二叉搜索树转换成双向链表

好一点点就是好一点点嘛 RT 传入3个参数 <根节点,上次访问的节点,头结点>.Yahoo二面被问到!完跪.... 1 void BST2DoubleList(TreeNode *root, TreeNode *& prev, TreeNode *& head) { 2 if (root == NULL) 3 return; 4 BST2DoubleList(root->left, prev, head); 5 root->left = prev; 6 if (pr

[leetcode]426. Convert Binary Search Tree to Sorted Doubly Linked List二叉搜索树转有序双向链表

Convert a BST to a sorted circular doubly-linked list in-place. Think of the left and right pointers as synonymous to the previous and next pointers in a doubly-linked list. Let's take the following BST as an example, it may help you understand the p

递归之(二叉搜索树和排序双向链表)

链接:https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 代码如下: 原文地址:https://www.cnblogs.com/zf-blog/p/9880108.html

二叉搜索树转双向链表

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向.比如输入下图中左边儿茶搜索树,则输出转换后的排序双向链表. 10 / 6 14 / \ / 4 8 12 16 4=6=8=10=12=14=16  将二叉搜索树转化为有序双向链表,类似于中序遍历,中序遍历的结果就是一个排序的数字.因此在程序中以中序遍历树,当遍历左子树到在叶子结点的时候,开始修改指针.  #include<iostream> #include<stdl