zoukankan      html  css  js  c++  java
  • 剑指offer[26]——二叉搜索树与双向链表

    题目描述

    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    这道题目是考察如何改变指针达到要求,什么是二叉搜索树在这里再放一下:

    二叉搜索树是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树,如下图所示就是一个二叉搜索树:
    image-20200313112016160

    根据这个图,我们其实可以看出,叶节点部分的最小二叉树按照左子树节点——根节点——右子树节点来排序的话恰好是一个从小到大排序的数组:

    这道题目的思路其实是我们先找到最大的节点,也就是一直向右子树找,直到右子树为空,那么这个节点就是值最大的节点,我们将其记录为pre,接下来我们要改变这个值最大的节点与他的父节点的指针指向,在这里我们用2327举例,首先将23的右子树指向27,然后将27的左子树指向23,这里要改变一下pre,将pre重新复制为27节点记录下来,以进行后续操作。这样就暂且完成了两个节点的连接,如下:

    接下来我们考虑一下23的左子树16的指针变化,很简单,将16的右子树指针指向23,然后再改变pre,将其赋值为16节点,如下:

    看到这里大家明白没有,pre记录的其实是从最大值节点开始,逐渐改为倒数第二大值节点和倒数第三大值节点,以此类推。所以我们没有只要改变pre记录的节点指针的指向就可以,pre以右的所有指针都是已经排好序的

    我这里考虑的是比较简单的情况,其实复杂的情况也是这个规律,找好规律让递归算法完成就可以了。

    /* function TreeNode(x) {
        this.val = x;
        this.left = null;
        this.right = null;
    } */
    
    function Convert(pRootOfTree)
    {
        let pre = null;
        function _Convert(_pRootOfTree){
            if(!_pRootOfTree){return null;}
            _Convert(_pRootOfTree.right);
            if(!pre){pre=_pRootOfTree;}
            else{
                _pRootOfTree.right = pre;
                pre.left = _pRootOfTree;
                pre = _pRootOfTree;
            }
            _Convert(_pRootOfTree.left);
            return pre;
        }
        return _Convert(pRootOfTree);
    }
    
  • 相关阅读:
    为用户添加角色
    WCF、MongoDB
    文件分布式存储实现例程
    Redis的Replication(复制)
    Lucene热词显示并选择
    Lucene热词统计
    通过队列解决Lucene文件并发创建索引
    Lucene.net应用
    Lucene.net
    Redis
  • 原文地址:https://www.cnblogs.com/Jacob98/p/12509485.html
Copyright © 2011-2022 走看看