二叉搜索树oj ----->二叉搜索树与双向链表

Posted ohana!

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉搜索树oj ----->二叉搜索树与双向链表相关的知识,希望对你有一定的参考价值。

题目内容:

 分析:

拿到这道题,首先可以观察到转换的最大特点就是将二叉搜索树以有序的状态表达出来了,因此,必须要考虑

(1)如何将其转换成有序

(2)其次考虑的是,怎么才能创建一个满足题目要求的双向链表

解题思路:

(1)用查找,改变指向的方式完成

  • 所谓查找就是进行第一步转换的过程--->中序遍历
  • 改变指向就是在遍历的过程将其前后指向从以前的树状结构重新指向为双向链表
  • 给一个prev的结点记录此时遍历的前一个结点,进行上述第二步的操作
  • 返回双向链表的头结点,本质就是中序遍历的第一个节点,即就是最左侧的那个结点,通过一次遍历,将其保存下来,直接返回即可

方式一代码示例: 

public class Solution 
    TreeNode parent = null;
    public void vin(TreeNode root)
        if(root != null)
            vin(root.left);
            //将此时的这个结点的左指向上一次保存的那个结点
            root.left = parent;
            //需要进行判断
            //1.如果是空,就不需要指向了,说明此时是第一个节点
            //2.如果不是空,就需要将上一个结点的右侧指向此时的结点
            if(parent != null)
                parent.right = root;
            
            //更新负责保存的结点
            parent = root;
            vin(root.right);
        
    
    public TreeNode Convert(TreeNode pRootOfTree) 
        //如果是空,就不需要改变了,直接返回
        if(pRootOfTree == null)
            return pRootOfTree;
        
        //进行保存头结点的操作
        TreeNode head = pRootOfTree;
        while(head.left != null)
            head = head.left;
        
        //传入结点
        vin(pRootOfTree);
        return head;
    

 (2)用保存,改变指向的方式来完成

  • 保存就是保存一个集合容器当中,此处我选择了ArrayList,因为他可以动态添加
  • 改变指向就是上面所说的,只不过这次我用循环的方式对每个结点进行了改变指向,而且从理解层度上来说,我觉得这种更好理解一点,先保存,后更改,更符合思维逻辑
  • 这次返回头结点,我们有两种方式,第一种就是上面的那种,第二种,因为这次已经保存了下来,所以直接返回顺序表的第一种元素就行了

代码示例:

public class Solution 
    List<TreeNode> list = new ArrayList<>();
    public List<TreeNode> vin(TreeNode root)
        if(root != null)
            vin(root.left);
            list.add(root);
            vin(root.right);
        
        return list;
    
    public TreeNode Convert(TreeNode pRootOfTree) 
        if(pRootOfTree == null)
            return pRootOfTree;
        
        /*
        TreeNode head = pRootOfTree;
        while(head.left != null)
            head = head.left;
        
        */
        
        List<TreeNode> list1 = new ArrayList<>();
        list1 = vin(pRootOfTree);
        for(int i = 1;i < list1.size();i++)
            list1.get(i - 1).right = list1.get(i);
            list1.get(i).left = list1.get(i - 1);
        
        return list1.get(0);
    

以上是关于二叉搜索树oj ----->二叉搜索树与双向链表的主要内容,如果未能解决你的问题,请参考以下文章

SDUT OJ 2610 Boring Counting(主席树)

Light OJ 1114 Easily Readable 字典树

算法导论OJ习题— 数据库查询(红黑树实现AVL树实现)

值域线段树 (玲珑OJ 1117)

BZOJ4811[Ynoi2017]由乃的OJ 树链剖分+线段树

[Comet OJ - Contest #6 C][48C 2279]一道树题_树