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

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;
};
画图不容易,帮顶,赐教!
























转载于:https://www.cnblogs.com/melons/p/5791850.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值