参考: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. 插件开发之360 DroidPlugin源码分析(一)初识

    转载请注明出处:http://blog.csdn.net/hejjunlin/article/details/52123450 DroidPlugin的是什么? 一种新的插件机制,一种免安装的运行机制 ...

  2. Hibernate之持久化状态

    可持久化对象有以下三种状态: 临时状态(Transient):对象在保存进数据库之前为临时状态,这时数据库中没有该对象的信息,如果没有持久化,程序退出后临时状态的对象信息将会丢失.随时可能被垃圾回收器 ...

  3. Android开发学习之路--UI之ListView

    这里再学习写android的ListView,其实我们都使用过ListView,就像手机的联系人,就是用的ListView了.下面就实现下简单的ListView吧,首先是xml文件中添加相关的代码: ...

  4. Redis简介以及数据类型存储

    由于我们在大型互联网项目当中,用户访问量比较大,比较多,会产生并发问题,对于此,我们该如何解决呢,Redis横空出世,首先,我们来简单的认识一下Redis,详细介绍如下所示: Redis是一个开源的, ...

  5. Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(二)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 首先在CatMazeV3中新建CatSprite类,继承于Spr ...

  6. Cocos2D中图片加-hd后缀的说明

    你可能注意到实际上游戏中的sprite都有2张图片,它都对应该精灵,并包含在资源包中(resource pack): player.png(27x40 pixels)和player-hd.png(do ...

  7. Unity UGUI图文混排源码(一)

    Unity UGUI图文混排源码(一):http://blog.csdn.net/qq992817263/article/details/51112304 Unity UGUI图文混排源码(二):ht ...

  8. VS2010中NET4项目中使用LOG4NET办法

    两年以前项目中是用的log4net.dll是net2.0环境下面的,最近在官网http://logging.apache.org/log4net/download_log4net.cgi找到了net4 ...

  9. cuda中模板的使用

    模板是C++的一个重要特征,它可以让我们简化代码,同时使代码更整洁.CUDA中也支持模板,这给我们编写cuda程序带来了方便.不过cuda4.0之前和之后使用模板的方法不一样,这给我们带来了少许困难. ...

  10. Java-ServletContextAttributeListener

    /** Implementations of this interface receive notifications of ** changes to the attribute list on t ...