• 【1】二元查找树转变成排序的双向链表


    题目:


    二元查找树【百度百科】

    它首先要是一棵二元树,在这基础上它或者是一棵空树;或者是具有下列性质的二元树:
    1. 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
    2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 
    3. 左、右子树也分别为二元查找树

    分析

    根据二元查找树的特点可知:节点A的左子树的值都小于A,A的右子树的值都大于A。
    1. 所以双向链表中,A的左边的值为左子树最右子树节点的值,而A的右边的值为右子树最左的子树节点的值,当然,这种分析不大适合直接写程序,效率不高
    2. 对于只有三个节点的二元查找树,很容易获取其排序后的顺序值:左节点<父节点<右节点。找到了上述的规律后,用递归的思想,情况就变得比较简单了,比如对于一个节点A,其左子树构成的顺序表为LA,右子树构成的顺序表为RA,那么A以及其子节点构成的顺序表则是:LA<A<RA,如此,使用递归就很容易获取结果顺序表了,然后对顺序链表处理一下,即可获得所需的双向链表
    3. 最后一种方法可根据树的遍历方法来排序的,还记得树的三种遍历方式(先序,中序,后续)?观察二元查找树的特殊性,发现:其左节点<中节点<右节点,这个顺序不是和树的中序遍历方式一样?那么可以直接套用二叉树的中序遍历来实现的啊!

    中序遍历实现二元查找树转换为双向链表源码

    class BSTreeNode
    {
    public:
    	int				_value;
    	BSTreeNode*		_pLeftTree;
    	BSTreeNode*		_pRightTree;
    	bool			_bSorted;
    	BSTreeNode(int value)
    	{
    		_value		= value;
    		_pLeftTree	= NULL;
    		_pRightTree	= NULL;
    		_bSorted	= false;
    	}
    };
    // 二叉树中序遍历
    void BTreeMid(BSTreeNode* r)
    {
    	stack<BSTreeNode*>	s;
    	BSTreeNode*			p = NULL;
    
    	s.push(r);
    	while(!s.empty())
    	{
    		p = s.top();
    		if(p && p->_bSorted == false)
    		{
    			s.push(p->_pLeftTree);
    		}
    		else
    		{
    			s.pop();
    			if(!s.empty())
    			{
    				p = s.top();
    				printf("%d ", p->_value);
    				p->_bSorted = true;
    				s.pop();
    				s.push(p->_pRightTree);
    			}
    		}
    	}
    }
    // 二叉树中序遍历转双向链表
    void BSTreeToDQ(BSTreeNode* r)
    {
    	stack<BSTreeNode*>	s;
    	BSTreeNode*			p = NULL;
    	BSTreeNode*			q = NULL;
    	BSTreeNode*			pHead = NULL;
    
    	s.push(r);
    	while(!s.empty())
    	{
    		p = s.top();
    		if(p && p->_bSorted == false)
    		{
    			s.push(p->_pLeftTree);
    		}
    		else
    		{
    			s.pop();
    			if(!s.empty())
    			{
    				p = s.top();
    				if(q)
    				{
    					p->_pLeftTree = q;
    					q->_pRightTree = p;
    				}
    				else
    				{
    					pHead = p;
    				}
    				q = p;
    				p->_bSorted = true;
    				s.pop();
    				s.push(p->_pRightTree);
    			}
    		}
    	}
    	q->_pRightTree = pHead;
    	pHead->_pLeftTree = q;
    
    	/*for (p=pHead; p!=pHead->_pLeftTree; p=p->_pRightTree)
    	{
    	printf("%d ", p->_value);
    	}*/
    }


    运行结果

  • 相关阅读:
    Android : reletive layout
    Android Studio 使用图片
    Android 笔记一:线性布局
    Qt笔记——右键菜单
    Qt笔记——连接第三方库&用libZPlay库获取音频文件的艺术家、专辑等信息
    git常用命令总结
    Qt项目——数字内容管理系统的参考资料和细节
    .Net转Java自学之路—基础巩固篇二十二(XML)
    .Net转Java自学之路—基础巩固篇二十一(模块化思想)
    .Net转Java自学之路—基础巩固篇二十(Lambda)
  • 原文地址:https://www.cnblogs.com/arbboter/p/4225197.html
Copyright © 2020-2023  润新知