文档章节

设计一个算法,找出二叉查找树中指定结点的“下一个“结点(也即中序后继)。可以假定每个结点都含有指向父结点的连接。

一贱书生
 一贱书生
发布于 2016/11/18 11:34
字数 1078
阅读 31
收藏 0

问题分析

假设需要查找 node 结点的下一个结点,需要考虑三种情况:

①node 节点有右孩子

下一个结点就是以node结点的右孩子为根的子树中的最左下结点。如下图:node=8,它的下一个结点为12.

 

②node 节点没有右孩子时,node节点是其父结点的左孩子。如下图,结点8的下一个结点是结点12

 

 

③node 节点没有右孩子时,node节点是其父结点的右孩子,如下图,结点14 的下一个结点是 结点16

 

 

 

如何在一棵二叉树中查找某个结点?

可以用先序遍历的思路。但是一定要注意递归的实现---第11行的 return target 是很有意义的。

在每一次的递归调用中,每个方法都有一个自己的 target 局部变量。如果在这个方法里面找到了目标结点,如果没有 return 返回的话,当递归回退时就会丢失“已找到的目标结点”----即上一层的 find 方法中的target 变量还是null(尽管在下一层递归中已经找到了目标结点)

通过第11行的 return 语句,如果在某一层还未找到目标结点,则会继续递归调用下去,如果找到了,在 return 的时候,上一层的find方法的target变量就不会为 null ,  从而在最终 find 方法结束时,返回找到的目标结点。

 

复制代码

 1     //采用先序遍历查找值为ele的结点
 2     private BinaryNode find(BinaryNode root, int ele){
 3         if(root == null)
 4             return null;
 5         if(root.ele == ele)
 6             return root;
 7         BinaryNode target = null;
 8         target = find(root.left, ele);
 9         if(target == null)//如果左子树中没有值为ele的结点,if成立,在右子树中查找
10             target = find(root.right, ele);
11         return target;
12     }

复制代码

①第3-4行是应对查找到叶子结点的情况

②第5-6行,是成功查找到了指定结点的情况。(①②类似于先序遍历中的访问根结点)

③第8行,表示先在左子树中查找(类似于先序遍历左子树)

④第9-10行if表示在左子树中未查找到该结点,则查找右子树⑤第11行,返回查找的结点。若返回null,表示未找到

 

三,代码分析

①node 节点有右孩子

复制代码

1 if(node.right != null)
2 {
3     BinaryNode current = node.right;
4     while(current.left != null)
5     {
6     current = current.left;
7     }
8     nextNode = current;
9  }

复制代码

第3行,先定位到node结点的右孩子。

第4行while循环,查找最左下结点

 

②node 节点没有右孩子时,node节点是其父结点的左孩子

1 else if(node.parent != null){//node结点 是 parent 的孩子
2     if(node.parent.left != null && node.parent.left.equals(node))// node 是 parent 的左孩子
3         nextNode = node.parent;

如果node节点是其父结点的左孩子,那么下一个结点就是node节点的父结点。

 

③node 节点没有右孩子时,node节点是其父结点的右孩子

复制代码

1 else{//node 是 parent的右孩子
2     BinaryNode current = node.parent;
3     //一直往着右孩子的父结点指针向上走
4     while(current.parent.right != null && current.parent.right.equals(current))
5     {
6         current = current.parent;
7     }
8     nextNode = current.parent;
9 }

复制代码

要注意第4行while循环中的第一个条件:current.parent.right != null

为什么不要判断 current.parent != null 呢?因为在前面的if语句中已经判断了(if(node.parent != null)

 

完整代码:

public class BSTNextNode {

    private class BinaryNode{
        int ele;
        BinaryNode left;
        BinaryNode right;
        BinaryNode parent;
        int hash;//cache hashCode
        
        public BinaryNode(int ele) {
            this.ele = ele;
            parent = left = right = null;
        }
        
        @Override
        public boolean equals(Object obj) {
            if(obj == null)
                return false;
            if(!(obj instanceof BinaryNode))
                return false;
            BinaryNode node = (BinaryNode)obj;
            return node.ele == this.ele;
        }
        
        @Override
        public int hashCode() {// 参考《effective java》中覆盖equals方法
            int result = hash;
            if(result == 0){
                result = 17;
                result = result*31 + ele;
                hash = result;
            }
            return result;
        }

或者:

 

下面是该算法的实现代码(已正确处理结点为空的情况)

public TreeNode inorderSucc(TreeNode n)
{
if(n==null) return null;
/*
找到右子结点,则返回右子树里最左边的结点
*/
if(n.right!=null)
{
return leftMostChild(n.right);
}
else
{
TreeNode q=n;
TreeNode x=q.parent;
//向上直至位于左边而不是右边
while(x!=null&&x.left!=q)
{
q=x;
x=x.parent;
}
return x;
}
}


public TreeNode leftMostChild(TreeNode n)
{
if(n==null)
return null;
while(n.left!=null)
{
n=n.left;
}
return null;

}

 

 

或者

 

 

© 著作权归作者所有

共有 人打赏支持
一贱书生
粉丝 19
博文 724
码字总数 600123
作品 0
Java数据结构和算法 - 二叉树

前言 数据结构可划分为线性结构、树型结构和图型结构三大类。前面几篇讨论了数组、栈和队列、链表都是线性结构。树型结构中每个结点只允许有一个直接前驱结点,但允许有一个以上直接后驱结点...

fireway
08/23
0
0
数据结构学习笔记-排序/队/栈/链/堆/查找树/红黑树

排序: 插入排序:每次从剩余数据中选取一个最小的,插入已经排序完成的序列中 合并排序:将数据分成左右两组分别排序,然后合并,对每组数据的排序递归处理。 冒泡排序:重复交换两个相邻元...

duanbowen
2017/05/26
0
0
算法知识梳理(10) - 二叉查找树

面试算法代码知识梳理系列 算法知识梳理(1) - 排序算法 算法知识梳理(2) - 字符串算法第一部分 算法知识梳理(3) - 字符串算法第二部分 算法知识梳理(4) - 数组第一部分 算法知识梳理(5) - 数...

泽毛
2017/12/18
0
0
二叉排序树(Binary Sort Tree)

1、定义 二叉排序树(Binary Sort Tree)又称二叉查找(搜索)树(Binary Search Tree)。其定义为:二叉排序树或者是空树,或者是满足如下性质的二叉树: ① 若它的左子树非空,则左子树上所有...

野渡书生
2016/04/28
96
0
字符串查找算法--R向单词查找树和三向单词查找树

字符串查找算法分析 算法对比: 算法(数据结构) 优点 二叉查找树(BST) 适用于随机排列的键 2-3树查找(红黑树) 有性能保证 线性探测法(并行数组) 内置类型,缓存散列值 R向单词查找树...

SuperHeroes
01/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

崩溃bug日志总结1

目录介绍 1.1 java.lang.UnsatisfiedLinkError找不到so库异常 1.2 java.lang.IllegalStateException非法状态异常 1.3 android.content.res.Resources$NotFoundException 1.4 java.lang.Ille......

潇湘剑雨
57分钟前
0
0
学习大数据为什么要先学Java?

计算机编程语言有很多,目前用的多一点的就是Java,C++,Python等等。目前大多数学习大数据的人都是选择学习Java,那Java到底好在哪呢?为什么学大数据之前要先学Java呢?我们今天就来分析一...

董黎明
今天
1
0
php删除服务器所有session

php删除服务器所有session踢掉所有在线用户linux 注意:如果要删除服务器上所有session,重启php服务是解决不了问题的,php的session是持久化的。 有效解决办法: 删除 /tmp 下的所有文件(默...

妖尾巴
今天
0
0
Ubuntu18.04 安装最新版WPS

1.手动卸载libreoffice:sudo apt-get remove --purge libreoffice* 2.官网下载WPS和字体: WPS:http://wps-community.org/download.html 字体:http://wps-community.org/download.html?vl......

AI_SKI
今天
4
0
数据结构(算法)-图(深度优先搜索 DFS)

#include <iostream>using namespace std;#define MaxVex 30typedef char VertexType;typedef struct vexNode adjList[MaxVex];struct edgeNode{int adjvex;//邻接点......

ashuo
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部