二叉查找树BST----java实现
二叉查找树BST----java实现
1.二叉查找树简单介绍
二叉查找树又名二叉搜索树和二叉排序树。性质例如以下:
在二叉查找树中:
(01) 若随意节点的左子树不空,则左子树上全部结点的值均小于它的根结点的值。
(02) 随意节点的右子树不空,则右子树上全部结点的值均大于它的根结点的值;
(03) 随意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。
2.二叉查找树节点类
class TreeNode
{
int value;
TreeNode parent;
TreeNode left;
TreeNode right;
public TreeNode(int value, TreeNode parent, TreeNode left, TreeNode right) {
this.value = value;
this.parent = parent;
this.left = left;
this.right = right;
}
}
3.遍历
二叉查找树的遍历同二叉树的遍历,递归与非递归方法详见《二叉树的递归遍历和非递归遍历(附具体样例)》
4.最大和最小值
a.BST中的最小值即最左的孩子。
//求BST的最小值
public TreeNode getMin(TreeNode root)
{
if(root==null)
return null;
while(root.left!=null)
root=root.left;
return root;
}
b.BST中的最大值即最右的孩子。
//求BST的最大值
public TreeNode getMax(TreeNode root)
{
if(root==null)
return null;
while(root.right!=null)
root=root.right;
return root;
}
5.前驱和后继节点
ps:图片来于网络
a.BST中某节点前驱节点==小于该节点的全部节点中的最大值
前驱easy情形:5寻前驱 4
前驱复杂情形:11寻前驱 10
//查找BST中某节点的前驱节点.即查找数据值小于该结点的最大结点。
public TreeNode preNode(TreeNode x)
{
if(x==null)
return null;
// 假设x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。 if(x.left!=null)
return getMax(x.left);
// 假设x没有左孩子。 则x有下面两种可能:
// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
// (02) x是"一个左孩子",则 前驱节点为x的某一个祖先节点的父节点,并且该祖先节点是作为其父节点的右儿子
TreeNode p=x.parent;
while(p!=null&&p.left==x)
{
x=p;//父节点置为新的x
p=p.parent; //父节点的父节点置为新的父节点
}
return p;
}
b.BST中某节点后继节点==大于该节点的全部节点中的最小值
后继easy情形:5寻后继 6
复杂情形:9寻后继 10
//查找BST中某节点的后继节点.即查找数据值大于该结点的最小结点。 public TreeNode postNode(TreeNode x)
{
if(x==null)
return null;
// 假设x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if(x.left!=null)
return getMin(x.right);
// 假设x没有右孩子。则x有下面两种可能:
// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
// (02) x是"一个右孩子",则 前驱节点为x的某一个祖先节点的父节点,并且该祖先节点是作为其父节点的左儿子
TreeNode p=x.parent;
while(p!=null&&p.right==x)
{
x=p;//父节点置为新的x
p=p.parent; //父节点的父节点置为新的父节点
}
return p;
}
6.查找
查找值为val的节点,假设小于根节点在左子树查找,反之在右子树查找
//查找值为val的节点 --递归版--
public TreeNode searchRec(TreeNode root ,int val)
{
if(root==null)
return root;
if(val<root.value)
return searchRec(root.left,val);
else if(val>root.value)
return searchRec(root.right,val);
else
return root;
}
//查找值为val的节点 --非 递归版--
public TreeNode search(TreeNode root ,int val)
{
if(root==null)
return root;
while(root!=null)
{
if(val<root.value)
root=root.left;
else if(val>root.value)
root=root.right;
else
return root;
}
return root;
}
7.插入
a.若当前的二叉查找树为空,则插入的元素为根节点
b.若插入的元素值小于根节点值。则将元素插入到左子树中
c.若插入的元素值不小于根节点值,则将元素插入到右子树中。首先找到插入的位置,要么向左,要么向右,直到找到空结点,即为插入位置,假设找到了同样值的结点,插入失败。
//BST插入节点 --递归版--
public TreeNode insertRec(TreeNode root,TreeNode x)
{
if(root==null)
root=x;
else if(x.value<root.value)
root.left=insertRec(root.left, x);
else if(x.value>root.value)
root.right=insertRec(root.right, x);
return root;
}
//BST插入节点 --非 递归版--
public TreeNode insert(TreeNode root,TreeNode x)
{
if(root==null)
root=x;
TreeNode p=null;//须要记录父节点
while(root!=null)//定位插入的位置
{
p=root;//记录父节点
if(x.value<root.value)
root=root.left;
else
root=root.right;
}
x.parent=p;//定位到合适的页节点的空白处后。依据和父节点的大小比較插入合适的位置
if(x.value<p.value)
p.left=x;
else if(x.value>p.value)
p.right=x;
return root;
}
8.删除
二叉查找树的删除,分三种情况进行处理:
1.p为叶子节点。直接删除该节点,再改动其父节点的指针(注意分是根节点和不是根节点),如图a。
2.p为单支节点(即仅仅有左子树或右子树)。
让p的子树与p的父亲节点相连,删除p就可以。(注意分是根节点和不是根节点);如图b。
3.有两个孩子的情况,当前结点与左子树中最大的元素交换。然后删除当前结点。左子树最大的元素一定是叶子结点,交换后。当前结点即为叶子结点。删除參考没有孩子的情况。还有一种方法是,当前结点与右子树中最小的元素交换,然后删除当前结点。如图c。
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc2hlZXBtdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
ps:图片来于网络
//BST删除节点
public void delete(TreeNode root,TreeNode x)
{
if(root==null)
return ;
TreeNode p=null;
while(root!=null)//定位到须要删除的节点
{
if(x.value<root.value)
{
p=root;//记录父节点
root=root.left;
}
else if(x.value>root.value)
{
p=root;//记录父节点
root=root.right;
}
else//找到啦
{
if(root.left==null&&root.right==null)//①待删除的是 叶子节点
{
if(p==null)//待删除的是根节点
root=null;
else
{
if(p.left==root)
p.left=null;
else if(p.right==root)
p.right=null;
}
}
else if(root.left!=null&&root.right==null)//② 待删除的节点仅仅有左孩子
{
if(p==null)//待删除的是根节点
root=root.left;
else
{
if(p.left==root)//待删除的本身是一个左孩子
p.left=root.left;
else if(p.right==root)
p.right=root.left;
}
}
else if(root.left==null&&root.right!=null)//② 待删除的节点仅仅有右孩子
{
if(p==null)//待删除的是根节点
root=root.right;
else
{
if(p.left==root)//待删除的本身是一个左孩子
p.left=root.right;
else if(p.right==root)
p.right=root.right; }
}
else//③待删除的节点即有左孩子又有右孩子 方法:得到待删除节点右子树的最小值。
{//该最小值与待删除节点进行“ 值 ”交换。删除该最小值位置处的节点
TreeNode rMin=root.right; //求待删除节点的后继节点,即待删除节点的右孩子的最小值(找到的后继节点肯定没有左孩子!!。)
TreeNode rMinP=null;//由于须要删除后继节点位置,所以须要记录父节点
while(rMin!=null)
{
rMinP=rMin;
rMin=rMin.left;
}
int rootVtemp=root.value;//值交换
root.value=rMin.value;
rMin.value=rootVtemp;
//删除rMin位置的节点,此时此位置的值已是待删节点的值
if(rMinP.left==rMin)
rMinP.left=rMin.right;
else if(rMinP.right==rMin)
rMinP.right=rMin.right;
}
}
break;//找到后删了后就跳出while循环
} }
9.二叉树查找树常见面试题
a.推断一个数组是不是二叉搜索树的后序遍历
package com.sheepmu; public class Offer24
{
public static void main(String[] args)
{
int[] a={5,7,6,9,11,10,8};
int len=a.length; System.out.println(isProOfBST(a,len));
}
public static boolean isProOfBST(int[] a,int len)
{
if(a==null||len<=0)
return false;
int root=a[len-1];//后序遍历的最后一个为根节点
int i=0;
while(a[i]<root)//找到左树的个数
i++;
int j=i;//先看右树中是否有非法数字,即比根节点小的数字
while(j<len-1)
{
if(a[j]<root)
return false;
j++;
}
//若左右子树的数字都合法,即左子树都比根的值小,右子树都比根节点大;此时仅仅需递归推断左右子树是否是二叉搜索树的后序遍历
//求左右子树的数组,到这儿明显发现用字符串非常爽呀直接subString()
boolean left=true;
if(i>0)//必需要推断是否存在左树
{
int[] aleft=new int[i];
for(int x=0;x<i;x++)
aleft[x]=a[x];
left=isProOfBST(aleft,i);
}
boolean right=true;
if(i<len-1)//必需要推断是否存在右树
{
int[] aright=new int[len-i-1];
// for(int y=i;y<len-1;y++)//粗心啊!!。! // {
// aright[y]=a[y];
// }
for(int y=0;y<len-i-1;y++)
aright[y]=a[i+y];
right=isProOfBST(aright,len-i-1);
}
return left&&right;
}
}
b.将一颗二叉搜索树转为为排序的双向链表
二叉查找树BST----java实现的更多相关文章
- 二叉查找树的Java实现
为了克服对树结构编程的恐惧感,决心自己实现一遍二叉查找树,以便掌握关于树结构编程的一些技巧和方法.以下是基本思路: [1] 关于容器与封装.封装,是一种非常重要的系统设计思想:无论是面向过程的函数,还 ...
- 查找系列合集-二叉查找树BST
一. 二叉树 1. 什么是二叉树? 在计算机科学中,二叉树是每个结点最多有两个子树的树结构. 通常子树被称作“左子树”(left subtree)和“右子树”(right subtree). 二叉树常 ...
- 二叉查找树(BST)
二叉查找树(BST):使用中序遍历可以得到一个有序的序列
- 二叉查找树之 Java的实现
参考:http://www.cnblogs.com/skywang12345/p/3576452.html 二叉查找树简介 二叉查找树(Binary Search Tree),又被称为二叉搜索树.它是 ...
- 二叉查找树BST 模板
二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东 ...
- [学习笔记] 二叉查找树/BST
平衡树前传之BST 二叉查找树(\(BST\)),是一个类似于堆的数据结构, 并且,它也是平衡树的基础. 因此,让我们来了解一下二叉查找树吧. (其实本篇是作为放在平衡树前的前置知识的,但为了避免重复 ...
- 【查找结构 2】二叉查找树 [BST]
当所有的静态查找结构添加和删除一个数据的时候,整个结构都需要重建.这对于常常需要在查找过程中动态改变数据而言,是灾难性的.因此人们就必须去寻找高效的动态查找结构,我们在这讨论一个非常常用的动态查找树— ...
- 二叉查找树(BST)的实现
一.二叉树介绍 二叉查找树(Binary Search Tree,BST),又称二叉排序树,也称二叉搜索树,它或者是一颗空树,或者具有如下性质的树:若它的左子树不为空,则左子树上所有节点的值都小于根节 ...
- 3.2 符号表之二叉查找树BST
一.插入和查找 1.二叉查找树(Binary Search Tree)是一棵二叉树,并且每个结点都含有一个Comparable的键,保证每个结点的键都大于其左子树中任意结点的键而小于其右子树的任意结点 ...
- 算法笔记_053:最优二叉查找树(Java)
目录 1 问题描述 2 解决方案 1 问题描述 在了解最优二叉查找树之前,我们必须先了解何为二叉查找树? 引用自百度百科一段讲解: 二叉排序树(Binary Sort Tree)又称二叉查找树(B ...
随机推荐
- maven学习(四)——maven项目构建过程
一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立Maven约定的目录结构和pom.xml文件 Hello | --src | -----main | ----- ...
- 微信小程序--问题汇总及详解之form表单
附上微信小程序开发文档链接:https://mp.weixin.qq.com/debug/wxadoc/dev/framework/MINA.html form表单: 当点击 <form/> ...
- 抓取js动态生成数据
最近在抓数据,一般的网页数据抓取相对容易一些,今天在抓电视猫的节目单,发现有些数据时抓取不到的,Java端得到的HTML文件里面没有某一段代码,查了很多资料,发现说是js动态生成的数据,无法直接抓取, ...
- xtrabackup安装使用说明
软件介绍: Percona XtraBackup是一块开源且免费的对MySQL Innodb存储引擎备份数据的工具,使用此工具的时候不需停止MySQL,而且支持压缩备份,支持对Innodb存储引擎做增 ...
- 【VBA】利用Range声明Array(一维/二维)
[说明] B2开始到B?(中间不能有空格),定义一维数组Arr_approver() Dim R_sh As Worksheet Set R_sh = ThisWorkbook.Sheets(&quo ...
- Xposed初体验
Xposed初体验 1 测试环境 硬件:小米2s 16GB 电信版 系统:MIUI 4.4.18(开发版) Xposed版本: 2.5 注:Xposed版本号必须大于2.3,MIUI系统版本号也必须大 ...
- 分布式存储ceph集群实践
1.环境规划,三台主机 10.213.14.51/24 10.213.14.52/24 10.213.14.53/24 集群网络 172.140.140.11. ...
- Java之Jenkins工具【转】
1.1 前言 Jenkins是一个用Java编写的开源的持续集成工具.在与Oracle发生争执后,项目从Hudson项目独立. Jenkins提供了软件开发的持续集成服务.它运行在Servlet容器中 ...
- 【HDOJ5951】Winning an Auction(博弈DP)
题意:A和B两个人做一个拍卖游戏.每一轮两人分别给出一个价格,出价高者获得该轮的物品,出价相同则奇数轮A优先,偶数轮B优先. 两个人的目标都是最大化自己的商品数量,给定轮数n与两人分别的总资金a,b, ...
- ckeditor自己用的配置文件config.js
原文发布时间为:2011-01-17 -- 来源于本人的百度文章 [由搬家工具导入] CKEDITOR.editorConfig = function(config) { // Define c ...