博客
关于我
剑指offer(牛客)---26.二叉搜索树与双向链表
阅读量:717 次
发布时间:2019-03-17

本文共 2002 字,大约阅读时间需要 6 分钟。

题目描述

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

 

牛客推荐:

/**public class TreeNode {    int val = 0;    TreeNode left = null;    TreeNode right = null;    public TreeNode(int val) {        this.val = val;    }}*/public class Solution {    public TreeNode Convert(TreeNode pRootOfTree) {        if(pRootOfTree==null)            return null;        if(pRootOfTree.left==null&&pRootOfTree.right==null)            return pRootOfTree;        // 1.将左子树构造成双链表,并返回链表头节点        TreeNode left = Convert(pRootOfTree.left);        TreeNode p = left;        // 2.定位至左子树双链表最后一个节点        while(p!=null&&p.right!=null){            p = p.right;        }        // 3.如果左子树链表不为空的话,将当前root追加到左子树链表        if(left!=null){            p.right = pRootOfTree;            pRootOfTree.left = p;        }        // 4.将右子树构造成双链表,并返回链表头节点        TreeNode right = Convert(pRootOfTree.right);        // 5.如果右子树链表不为空的话,将该链表追加到root节点之后        if(right!=null){            right.left = pRootOfTree;            pRootOfTree.right = right;        }        return left!=null?left:pRootOfTree;           }}

 

解题思路:

假设有如下搜索二叉树:

 第一次判断一直到 TreeNode left = Convert(pRootOfTree.left);,然后一直遍历到结点6之后判断它的左右孩子都为null,返回null,现在left=null;pRootOfTree=节点6;

然后一直判断都为null,所以递归pRootOfTree(节点6)的右孩子( TreeNode right = Convert(pRootOfTree.right)),右孩子为空,返回null,right=null,最后判断返回当前pRootOfTree(6);然后继续递归,回到pRootOfTree(节点9),返回left=6,p=left=6然后一直判断到 if(left!=null),进入将节点9接到结点6的右孩子上面,结点6放到节点9的最还在上面;

相当于:

 又递归TreeNode right = Convert(pRootOfTree.right),pRootOfTree(9),有右孩子,右孩子10没有左右还在,所以直接返回当前结点10,将节点10的左孩子指向pRootOfTree(结点9),结点9的右孩子指向10,结构如图所示:

又递归完毕,往上走,TreeNode left = Convert(pRootOfTree.left);到了pRootOfTree(节点12),left(节点9),p=left(节点9),

while(p!=null&&p.right!=null){

            p = p.right;
        }

满足条件:这时候p的右孩子是10,所以当前p(结点10);

if(left!=null){

            p.right = pRootOfTree;
            pRootOfTree.left = p;
        }

满足条件:pRootOfTree(结点12)加入到排序链表中将当前结点如下图所示:

 后面就不在分析了,一直递归判断就可以了;

总结:从最左子树开始判断,因为他是链表的头,然后如果有右孩子就放他后面,没有的递归回去,父节点放到它后面,然后判断父节点有没有右孩子,有的话放到后面接起来,然后继续递归,巧妙之处在于right作为链表的下一个指向结点,left作为父节点.

转载地址:http://oubhz.baihongyu.com/

你可能感兴趣的文章
Mysql 拼接多个字段作为查询条件查询方法
查看>>
mysql 排序id_mysql如何按特定id排序
查看>>
Mysql 提示:Communication link failure
查看>>
mysql 插入是否成功_PDO mysql:如何知道插入是否成功
查看>>
Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
查看>>
mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
查看>>
mysql 数据库备份及ibdata1的瘦身
查看>>
MySQL 数据库备份种类以及常用备份工具汇总
查看>>
mysql 数据库存储引擎怎么选择?快来看看性能测试吧
查看>>
MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
查看>>
MySQL 数据库的高可用性分析
查看>>
MySQL 数据库设计总结
查看>>
Mysql 数据库重置ID排序
查看>>
Mysql 数据类型一日期
查看>>
MySQL 数据类型和属性
查看>>
mysql 敲错命令 想取消怎么办?
查看>>
Mysql 整形列的字节与存储范围
查看>>
mysql 断电数据损坏,无法启动
查看>>
MySQL 日期时间类型的选择
查看>>
Mysql 时间操作(当天,昨天,7天,30天,半年,全年,季度)
查看>>