zoukankan      html  css  js  c++  java
  • 二叉搜索树(搜索二叉树)转换成一个双向链表

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
























  • 相关阅读:
    TQ2440之I2C操作
    TQ2440之流水灯
    k8s pod注入环境变量
    k8s pod基本概念
    k8s pod存在的意义
    vscode 前端常用插件
    docker swarm常用命令
    k8s pod重启策略和健康检查实现应用自动修复
    k8s init初始化容器应用
    k8s pod状态管理
  • 原文地址:https://www.cnblogs.com/melons/p/5791850.html
Copyright © 2011-2022 走看看