二叉搜索树(搜索二叉树)转换成一个双向链表

1.题目描述:

将一个二叉搜索树转换成一个双向链表;

2.二叉搜索树,直接看图:

如图就是一个二叉搜索树的模型,也就是转换函数的入口数据,也是下边函数中即将用到的例子,既然有输入,肯定有输出,先面在看一张图(第三条):

3.输入输出模型:

右边就是最终的输出结果,5后边是空,下边来分析一下:

1.在二叉搜索树中,每个节点都有两个孩子,即左和右,而在双向链表中,每个节点也有两个指针,前驱和后继指针,二叉树和双向链表很有相似性;

2.改变二叉搜索树的左右孩子指针指向,就可完成二叉搜索树到双向链表的转换;

3.由于最终双向链表的遍历结果就是二叉搜索树中序的遍历结果;

4.开始中序线索化二叉树(即改变二叉树指针指向)

如果对中序线索化二叉树还有疑问,请看下图:

如图叶子节点的左右孩子指针指向都按中序线索的方式改变了;

4.看代码说话:

第一部分:

首先需要保存最后双向链表的头,即二叉树的最左节点:

Node* _BinaryToDoubleList(Node* root)
	{
		//1.找到双向链表的头;
		Node* head = root;
		while(head->_left != nullptr)
		{
			head = head->_left;
		}

		Node* prev = nullptr;
		_Change(root,prev);    //转换函数

		return head;
	}

第二部分:

转换函数:一个递归过程,按照中序线索化走的

	void _Change(Node* cur,Node*& prev)
	{
		if (cur == nullptr)
			return;
		//1.找到最左边
		_Change(cur->_left,prev);
		cur->_left = prev;  //此时prev为空

		if (prev != nullptr)
			prev->_right = cur;

		prev = cur;

		_Change(cur->_right, prev);
	}

完整测试代码:

#pragma once

template<class K, class V>
struct SBTNode
{
	K key;
	V value;

	SBTNode<K, V> *_left;
	SBTNode<K, V> *_right;

	SBTNode(const K& key, const V& value)
		:key(key)
		, value(value)
		, _left(nullptr)
		, _right(nullptr)
	{}
};

template<class K, class V>
class SBTree
{
	typedef SBTNode<K, V> Node;
public:
	SBTree()
		:_root(nullptr)
	{}

	~SBTree()
	{}

public:
	//非递归插入
	bool Insert(const K& key, const V& value)
	{
		return _Insert(key, value);
	}

	//递归插入
	bool Insert_R(const K& key, const V& value);

	//非递归查找节点
	SBTNode<K, V>* Find(const K& key)
	{
		if (_root == nullptr)
		{
			return nullptr;
		}

		SBTNode<K, V> *cur = _root;
		while (cur->_left || cur->_right)
		{
			if (cur->key == key)
			{
				return cur;
			}
			else if (cur->key > key)
			{
				cur = cur->_left;
			}
			else if (cur->key < key)
			{
				cur = cur->_right;
			}
			else
			{
				return nullptr;
			}
		}
	}

	bool _Insert(const K& key, const V& value)
	{
		if (_root == nullptr)
		{
			_root = new SBTNode<K, V>(key, value);
			return true;
		}

		SBTNode<K, V> *parent = nullptr; //指向cur 的前驱
		SBTNode<K, V> *cur = _root;
		while (cur)
		{
			if (cur->key > key)  //插左边
			{
				parent = cur;
				cur = cur->_left;
			}
			else if (cur->key < key)
			{
				parent = cur;
				cur = cur->_right;
			}
			else
			{
				return false;
			}
		}

		if (parent->key < key)
		{
			SBTNode<K, V> *node = new SBTNode<K, V>(key, value);
			parent->_right = node;
			return true;
		}

		else if (parent->key > key)
		{
			SBTNode<K, V> *node = new SBTNode<K, V>(key, value);
			parent->_left = node;
			return true;
		}
		else
		{
			return false;
		}
	}

	Node* BinaryToDoubleList()
	{
		return _BinaryToDoubleList(_root);
	}

	Node* _BinaryToDoubleList(Node* root)
	{
		//1.找到双向链表的头;
		Node* head = root;
		while(head->_left != nullptr)
		{
			head = head->_left;
		}

		Node* prev = nullptr;
		_Change(root,prev);    //转换函数

		return head;
	}

	void _Change(Node* cur,Node*& prev)
	{
		if (cur == nullptr)
			return;
		//1.找到最左边
		_Change(cur->_left,prev);
		cur->_left = prev;  //此时prev为空

		if (prev != nullptr)
			prev->_right = cur;

		prev = cur;

		_Change(cur->_right, prev);
	}

	//中序遍历
	void InOrder(SBTNode<K, V>* root)
	{
		if (root == nullptr)
		{
			return; //递归结束出口
		}

		SBTNode<K, V> *cur = root;
		InOrder(cur->_left);
		cout << cur->key << " ";
		InOrder(cur->_right);
	}

	//顺序遍历双向链表
	void TreaveList()
	{
		Node* cur = BinaryToDoubleList();
		while (cur)
		{
			cout << cur->key<< " ";
			cur = cur->_right;
		}
		cout << endl;
	}

public:
	SBTNode<K, V> *_root;
};

画图不容易,帮顶,赐教!

时间: 2024-07-30 11:16:23

二叉搜索树(搜索二叉树)转换成一个双向链表的相关文章

二叉搜索树(排序二叉树)

完整代码:插入,查找,删除 struct BST { int val; BST *lch, *rch; BST *insert(BST *p, int x) { if (p == NULL) { BST *t = new BST; //new出来的不是指向NULL的 t->val = x; t->lch = t->rch = NULL; return t; } if (x <= p->val) p->lch = insert (p->lch, x); else p

平衡二叉搜索树/AVL二叉树 C实现

//AVTree.h 1 #ifndef MY_AVLTREE_H 2 #define MY_AVLTREE_H 3 typedef int ElementType; 4 struct TreeNode 5 { 6 ElementType data; 7 struct TreeNode *left; 8 struct TreeNode *right; 9 int height; 10 }; 11 typedef struct TreeNode TreeNode; 12 typedef TreeN

C++二叉搜索树与双向链表(剑指Offer精简版)

题目:输入一棵二叉搜索树,将该二叉搜素树转换成一个排序的双向链表.二叉树节点定义如下: struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } }; 解题思路:由于通过中序排序可以转化为双向链表,因此,通过中序遍历的方法(左根右)的递归方法可以解决问题,解决完之后,pList节点指向双向链表的尾结点

二叉搜索树(Binary Search Tree)--C语言描述(转)

图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩子(当然了,存在的话)的值总是小于本身,而右孩子(存在的话)的值总是大于本身. 下面来介绍在此种二叉树结构上的查找,插入,删除算法思路. 查找:因为这种结构就是为了来方便查找的,所以查找其中的某个值很容易,从根开始,小的往左找,大的往右找,不大不小的就是这个节点了: 代码很简单,这里就不写了. 插入:插入一样的道理,从根开始,小的往左,大的往右,直到叶子,就插入.

二叉搜索树(Binary Search Tree)--C语言描述

一:硬着头皮就是上 数据结构中有个东西一直不愿意去面对,就是二叉搜索树,以及平衡二叉树.想想就耗脑细胞 马上开学了,就要学C++了,还有其他的事,估计更没有时间搞数据结构了,于是狠下心,把二叉搜索树和平衡二叉树给拿下!! 啊啊啊啊,算法很枯燥无聊,不过搞明白了收获多多,不过目前好像没有什么用. 反正安慰自己,这都是内功,修炼好了,以后放大招威力无比啊,嘿嘿. 二:图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩

输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。

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

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

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中节点的指针指向.二叉树的结点定义如下: struct BinaryTreeNode {         int m_nValue;     BinaryTreeNode* m_pLeft;     BinaryTreeNode* m_pRight; } 利用递归来解决问题 BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree) {     Bi

二叉树之二叉搜索树(BSTree)

二叉搜索树(Binary Search Tree) 二叉搜索树是一种二叉树,子结点数量上限为2:为了方便搜索,结点是有序的,左结点的key不大于父节点,右节点的key不小于父节点,且左右子树也是二叉搜索树. 下面是一个二叉搜索树的样图,来自维基 一棵树一般都要提供一些函数,例如遍历.搜索.最大最小值.插入,删除,销毁等 代码含注释,下面是输出效果(msys2) 代码 开发环境:Qt Creator 4.8.2 Mingw64 7.3 windows 8.1 完整代码:https://github

二叉树学习二:二叉搜索树

二叉搜索树(Binary Search Tree),或者是一棵空树,或者: 1)若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 2)若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 3)二叉搜索树的左.右子树也分别为二叉搜索树. 搜索二叉树相关的算法实现: 1)搜索二叉树的创建与转化为双链表实现: 1 #include "stdafx.h" 2 #include<iostream> 3 using namespace std; 4 5 /*二无