参考:http://www.cnblogs.com/skywang12345/p/3576452.html

二叉查找树简介

二叉查找树(Binary Search Tree),又被称为二叉搜索树。
它是特殊的二叉树:对于二叉树,假设x为二叉树中的任意一个结点,x节点包含关键字key,节点x的key值记为key[x]。如果y是x的左子树中的一个结点,则key[y] <= key[x];如果y是x的右子树的一个结点,则key[y] >= key[x]。那么,这棵树就是二叉查找树。如下图所示:

在二叉查找树中:
(01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(03) 任意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。

二叉查找树的Java实现

1. 二叉查找树节点的定义

public class BSTree<T extends Comparable<T>> {

    private BSTNode<T> mRoot;    // 根结点

    public class BSTNode<T extends Comparable<T>> {
T key; // 关键字(键值)
BSTNode<T> left; // 左孩子
BSTNode<T> right; // 右孩子
BSTNode<T> parent; // 父结点 public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right) {
this.key = key;
this.parent = parent;
this.left = left;
this.right = right;
}
} ......
}

BSTree是二叉树,它保护了二叉树的根节点mRoot;mRoot是BSTNode类型,而BSTNode是二叉查找树的节点,它是BSTree的内部类。BSTNode包含二叉查找树的几个基本信息:
(01) key -- 它是关键字,是用来对二叉查找树的节点进行排序的。
(02) left -- 它指向当前节点的左孩子。
(03) right -- 它指向当前节点的右孩子。
(04) parent -- 它指向当前节点的父结点。

2 遍历

这里讲解前序遍历、中序遍历、后序遍历3种方式。

2.1 前序遍历
若二叉树非空,则执行以下操作:
(01) 访问根结点;
(02) 先序遍历左子树;
(03) 先序遍历右子树。

前序遍历代码

private void preOrder(BSTNode<T> tree) {
if(tree != null) {
System.out.print(tree.key+" ");
preOrder(tree.left);
preOrder(tree.right);
}
} public void preOrder() {
preOrder(mRoot);
}

2.2 中序遍历

若二叉树非空,则执行以下操作:
(01) 中序遍历左子树;
(02) 访问根结点;
(03) 中序遍历右子树。

中序遍历代码

private void inOrder(BSTNode<T> tree) {
if(tree != null) {
inOrder(tree.left);
System.out.print(tree.key+" ");
inOrder(tree.right);
}
} public void inOrder() {
inOrder(mRoot);
}

2.3 后序遍历

若二叉树非空,则执行以下操作:
(01) 后序遍历左子树;
(02) 后序遍历右子树;
(03) 访问根结点。

后序遍历代码

private void postOrder(BSTNode<T> tree) {
if(tree != null)
{
postOrder(tree.left);
postOrder(tree.right);
System.out.print(tree.key+" ");
}
} public void postOrder() {
postOrder(mRoot);
}

看看下面这颗树的各种遍历方式:

对于上面的二叉树而言,
(01) 前序遍历结果: 3 1 2 5 4 6
(02) 中序遍历结果: 1 2 3 4 5 6 
(03) 后序遍历结果: 2 1 4 6 5 3

3. 查找

递归版本的代码

/*
* (递归实现)查找"二叉树x"中键值为key的节点
*/
private BSTNode<T> search(BSTNode<T> x, T key) {
if (x==null)
return x; int cmp = key.compareTo(x.key);
if (cmp < 0)
return search(x.left, key);
else if (cmp > 0)
return search(x.right, key);
else
return x;
} public BSTNode<T> search(T key) {
return search(mRoot, key);
}

非递归版本的代码

/*
* (非递归实现)查找"二叉树x"中键值为key的节点
*/
private BSTNode<T> iterativeSearch(BSTNode<T> x, T key) {
while (x!=null) {
int cmp = key.compareTo(x.key); if (cmp < 0)
x = x.left;
else if (cmp > 0)
x = x.right;
else
return x;
} return x;
} public BSTNode<T> iterativeSearch(T key) {
return iterativeSearch(mRoot, key);
}

4. 最大值和最小值

查找最大值的代码

/*
* 查找最大结点:返回tree为根结点的二叉树的最大结点。
*/
private BSTNode<T> maximum(BSTNode<T> tree) {
if (tree == null)
return null; while(tree.right != null)
tree = tree.right;
return tree;
} public T maximum() {
BSTNode<T> p = maximum(mRoot);
if (p != null)
return p.key; return null;
}

查找最小值的代码

/*
* 查找最小结点:返回tree为根结点的二叉树的最小结点。
*/
private BSTNode<T> minimum(BSTNode<T> tree) {
if (tree == null)
return null; while(tree.left != null)
tree = tree.left;
return tree;
} public T minimum() {
BSTNode<T> p = minimum(mRoot);
if (p != null)
return p.key; return null;
}

 

6. 插入

插入节点的代码:

public  BinaryNode<T> insert(T x,BinaryNode<T> t)
{
  if(t==null)
    return new BinaryNode<>(x,null,null);
  
  int r=x.compareTo(t.element);
  if(r<0)
    t.left=insert(x,t.left);
  else if(r>0)
    t.right=insert(x,t.right);
  else
    ;//重复,不做   return t;
}

7. 删除

删除节点的代码

如果节点是一片树叶,则直接被删除;如果节点有一个儿子,用儿子代替此节点;如果有两个儿子,用其右子树的最小数据代替该节点的数据,并删除右子树的该节点(最小节点),此时不能直接用右子树的最小节点代替此节点,因为最小节点可能有孩子,直接代替,就会混乱。

public BinaryNode<T> remove(T x,BinaryNode<T> t){
  if(t==null)
    return t;
  
int r=x.compareTo(t.element); if(r<0)
  t.left=remove(x,t.left);
else if(r>0)
  t.right=remove(x,t.right);
//找到节点以后
else if(t.left!=null&&t.right!=null)//两个儿子
{
  t.element=findMin(t.right).element;
  t.right=remove(t.element,t.right);
}
else //一个儿子。这种情况同时也包含了没有孩子的情况。左节点不为空就用左节点代替,如果左节点为空,则用右节点代替,右节点也可能为空。
  t=(t.left!=null)?t.left:t.right; return t; }

 

 

二叉查找树之 Java的实现的更多相关文章

  1. 二叉查找树的Java实现

    为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思路: [1] 关于容器与封装.封装,是一种非常重要的系统设计思想:无论是面向过程的函数,还 ...

  2. 数据结构--二叉查找树的java实现

    上代码: package com.itany.erchachazhaoshu; public class BinarySearchTree<T extends Comparable<? s ...

  3. 算法笔记_053:最优二叉查找树(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 在了解最优二叉查找树之前,我们必须先了解何为二叉查找树? 引用自百度百科一段讲解: 二叉排序树(Binary Sort Tree)又称二叉查找树(B ...

  4. 数据结构笔记--二叉查找树概述以及java代码实现

    一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...

  5. 二叉查找树(三)之 Java的实现

    概要 在前面分别介绍了"二叉查找树的相关理论知识,然后给出了二叉查找树的C和C++实现版本".这一章写一写二叉查找树的Java实现版本. 目录 1. 二叉树查找树2. 二叉查找树的 ...

  6. Java实现二叉查找树

    摘要:一个二叉查找树的Java实现.可以学习二叉树处理的递归及非递归技巧. 难度:初级. 为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思 ...

  7. 伸展树(三)之 Java的实现

    概要 前面分别通过C和C++实现了伸展树,本章给出伸展树的Java版本.基本算法和原理都与前两章一样.1. 伸展树的介绍2. 伸展树的Java实现(完整源码)3. 伸展树的Java测试程序 转载请注明 ...

  8. 树的基本概念以及java实现二叉树

    树具有的特点有: (1)每个结点有零个或多个子结点 (2)没有父节点的结点称为根节点 (3)每一个非根结点有且只有一个父节点 (4)除了根结点外,每个子结点可以分为多个不相交的子树.   树的基本术语 ...

  9. 16.检查是否为BST

    题目描述 请实现一个函数,检查一棵二叉树是否为二叉查找树. 给定树的根结点指针TreeNode* root,请返回一个bool,代表该树是否为二叉查找树 import java.util.*; /* ...

随机推荐

  1. Dynamics CRM 注册插件dll到GAC

    以server2012为例,搜索cmd,打开红框中的命令框,gacutil.exe -i "dll路径" 通过该命令把需要用到dll注册进gac(这里包括你的插件dll和你插件中引 ...

  2. 【Unity Shaders】游戏性和画面特效——创建一个夜视效果的画面特效

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  3. CentOS 64-bit下安装JDK和Tomcat并设置Tomcat开机启动操作步骤

    准备文件如下: 1.CentOS-6.4-x86_64-bin-DVD1.iso 2.jdk-7u67-linux-x64.rpm 3.apache-tomcat-7.0.55.tar.gz 安装步骤 ...

  4. 文件夹或者文件比对工具 Beyond Compare

    文件夹或者文件比对工具 Beyond Compare 之前有同事离职了.       没有工作交接.       同事的代码有一部分也没有提交版本库.       结果就是线上的代码和版本库中的文件数 ...

  5. mysql聚集索引

    转自http://www.cnblogs.com/tuyile006/archive/2009/08/28/1555615.html 微软的SQL SERVER提供了两种索引:聚集索引(cluster ...

  6. Chipmunk僵尸物理对象的出现和解决(四)

    接上一篇,我们看看五角星和反弹棒碰撞时的代码: -(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair star:(CCNode * ...

  7. 【一天一道LeetCode】#76. Minimum Window Substring

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...

  8. 关于学习MMU的一点感想

    MMU的一个主要服务是能把各个人物作为各自独立的程序在其自己的虚拟存储空间中运行. 虚拟存储器系统的一个重要特征是地址重定位.地址重定位是将处理器核产生的地址转换到主存的不同地址,转换由MMU硬件完成 ...

  9. saiku中文查询(鉴于有人提问:saiku执行mdx,有中文报错)

    有人问我saiku的中文查询问题: saiku默认执行英文,很多人,在mysql里录入了中文,使用sql语言查询没有问题. 可是,用saiku的mdx查询,就会报错. 这是因为mysql默认支持中文查 ...

  10. 《java入门第一季》之面向对象(static关键字内存图解)