二叉搜索树BStree
二叉搜索树,实际上是有点类似于二分查找。实际上很简单,就是递归。直接上代码,有点要注意的就是删除的时候,如果是左子树和右子树都存在的话,要寻找继承者(successor).
import java.util.HashMap;
import java.util.Map;
import java.util.Stack; public class BSTreeComparable<T extends Comparable> { private transient Node root; private static final String SUCCESSOR="successor"; private static final String SUCCESSOR_PARENT="parent"; private static final Node EMPTY_NODE = new Node(null,null,null,"empty node"); public BSTreeComparable() { //初始化为一个空树
root = null;
} /**
* 查询数据方法
* @param key
* @return
*/
public Node get(T key){
if(root ==null) return null;
Node node = getRecursive(root,key);
if(node ==null) return EMPTY_NODE;
return node;
} /**
* 往BST中插入数据
* @param key
* @param value
*/
public void put(T key,Object value){
if (root == null){
root = new Node(null,null,key,value);
}else{
putRecursive(root,key,value);
} } public void remove(T key){
Node newTree = remove(root,key);
root = newTree;
} private Node remove(Node tree ,T key){
if(tree==null) return null; //先递归去找到这个节点
if (key.compareTo(tree.key) < 0) {
tree.leftNode = remove(tree.leftNode, key);
return tree;
}
else if (key.compareTo(tree.key) > 0) {
tree.rightNode = remove(tree.rightNode, key);
return tree;
}// 相等说明已经找到这个节点了
else{
//case 1 假如这个节点左子树为空,则右子树顶包
if (tree.leftNode == null && tree.rightNode!=null) {
Node rightTree = tree.rightNode;
tree=null;
return rightTree;
}
//case 2 假如这个节点右子树为空,则左子树顶包
else if (tree.rightNode == null&& tree.leftNode!=null){
Node leftTree = tree.leftNode;
tree=null;
return leftTree;
//case 3 是叶子节点
}else if(tree.rightNode == null&& tree.leftNode==null){
tree=null; return null; }
//case 4 假如这个节点左右子树都不为空,则找到右子树种的最小值顶包
else{
Node toBeDeleted = tree;
Map map = getSuccessor(tree.rightNode,null);
Node successor = (Node) map.get(SUCCESSOR);
Node successorParent = (Node) map.get(SUCCESSOR_PARENT);
//如果successorParent是null的话,说明successor就是右节点
if(successorParent==null){
successor.leftNode = toBeDeleted.leftNode;
tree=null;
toBeDeleted =null;
return successor;
}else{
successor.leftNode = toBeDeleted.leftNode;
successor.rightNode = toBeDeleted.rightNode;
successorParent.leftNode =null;
tree=null;
toBeDeleted =null;
return successor;
}
}
}
} private Map<String,Node> getSuccessor(Node tree,Map<String,Node> map) {
if (map == null) {
map = new HashMap<>();
}
if (tree.leftNode == null){
map.put(SUCCESSOR,tree);
return map;
}
map.put(SUCCESSOR_PARENT,tree);
Map<String,Node> map2 = getSuccessor(tree.leftNode,map);
return map2;
} private Node putRecursive(Node tree,T key,Object value){
if(tree==null) return new Node(null,null,key,value);
if(key.compareTo(tree.key)<0){
tree.leftNode = putRecursive(tree.leftNode,key,value);
}else if(key.compareTo(tree.key)>0){
tree.rightNode = putRecursive(tree.rightNode,key,value);
}else{
tree.content = value;
}
return tree;
} /**
* 递归比较大小,如果小于该节点,则拿左节点继续比较
* 如果大于该节点,就拿右节点继续比较
* @param tree
* @param key
* @return
*/
private Node getRecursive(Node tree,T key){
if(tree==null) return null;
if(key.compareTo(tree.key)<0){
return getRecursive(tree.leftNode,key);
}else if(key.compareTo(tree.key)>0){
return getRecursive(tree.rightNode,key);
}else{
return tree;
}
} public static int getHeight(Node root) { if (root == null) {
return 0;
}
int leftHeight = 0;//记录左子树的树高
int rightHeight = 0;//记录右子树树高
if (root.leftNode != null) {//左子树不为空
leftHeight += getHeight(root.leftNode) + 1;//实际就是左子树树高的累计,加上root节点,如果不加1,得到的就是最大子树的树高,不好root节点
}
if (root.rightNode != null) {
rightHeight += getHeight(root.rightNode) + 1;
}
return leftHeight >= rightHeight ? leftHeight : rightHeight;
}
public void displayTree(){
Stack globalStack = new Stack();
globalStack.push(root);
int treeHeight = getHeight(root);
int nBlanks = (int) Math.pow(2d,(double)treeHeight);
boolean isRowEmpty = false;
System.out.println("=========================================================================");
while(!isRowEmpty) {
Stack localStack = new Stack();
isRowEmpty = true;
for (int j =0;j<nBlanks;j++) {
System.out.print(" ");
} while (!globalStack.isEmpty()) {
Node temp = (Node)globalStack.pop();
if (temp!=null) {
System.out.print(temp.key);
localStack.push(temp.leftNode);
localStack.push(temp.rightNode);
if (temp.leftNode != null || temp.rightNode !=null) {
isRowEmpty = false;
}
}
else {
System.out.print("--");
localStack.push(null);
localStack.push(null);
}
for (int j = 0;j<nBlanks*2-2;j++) {
System.out.print(" ");
}
}
System.out.println();
nBlanks /= 2;
while (!localStack.isEmpty()) {
globalStack.push(localStack.pop());
}
}
System.out.println("=========================================================================");
} static final class Node<T>{
public Node leftNode;
public Node rightNode;
public T key;
public Object content; public Node(Node leftNode, Node rightNode, T key, Object content) {
this.leftNode = leftNode;
this.rightNode = rightNode;
this.key = key;
this.content = content;
}
}
}
下面是测试代码:
public class BSTreeComparableTest {
public static void main(String[] args) {
BSTreeComparable tree = new BSTreeComparable();
tree.put(20,"20");
tree.put(10,"10");
tree.put(7,"7");
tree.put(4,"4");
tree.put(30,"30");
tree.put(40,"40");
tree.put(14,"14");
tree.put(12,"12");
tree.put(15,"15");
//tree.remove(12);
//tree.remove(30);
//tree.remove(7);
tree.remove(10);
tree.displayTree();
}
}
觉得写的好的,点个赞,谢谢,大冬天晚上,很辛苦的(◔◡◔)
二叉搜索树BStree的更多相关文章
- 基于visual Studio2013解决算法导论之029二叉搜索树
题目 二叉搜索树 解决代码及点评 #include <stdio.h> #include <malloc.h> #include <stdlib.h> ty ...
- 二叉搜索树(Binary Search Tree)--C语言描述(转)
图解二叉搜索树概念 二叉树呢,其实就是链表的一个二维形式,而二叉搜索树,就是一种特殊的二叉树,这种二叉树有个特点:对任意节点而言,左孩子(当然了,存在的话)的值总是小于本身,而右孩子(存在的话)的值总 ...
- 【剑指offer】二叉搜索树转双向链表
转载请注明出处:http://blog.csdn.net/ns_code/article/details/26623795 题目描写叙述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表. ...
- 数据结构-二叉树(应用篇)-之二叉搜索树 C和C++的实现
一.概念 二叉搜索树(Binary Sort Tree/Binary Search Tree...),是二叉树的一种特殊扩展.也是一种动态查找表. 在二叉搜索树中,左子树上所有节点的均小于根节点,右子 ...
- Java与算法之(13) - 二叉搜索树
查找是指在一批记录中找出满足指定条件的某一记录的过程,例如在数组{ 8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15 }中查找数字15,实现代码很简单 ...
- 【Java】 大话数据结构(11) 查找算法(2)(二叉排序树/二叉搜索树)
本文根据<大话数据结构>一书,实现了Java版的二叉排序树/二叉搜索树. 二叉排序树介绍 在上篇博客中,顺序表的插入和删除效率还可以,但查找效率很低:而有序线性表中,可以使用折半.插值.斐 ...
- 使用C++实现二叉搜索树的数据结构
需要注意的地方: ①二叉搜索树删除一个指定结点R,若R为叶子结点,则将R的父结点中指向R的指针改为指向nullptr:若R的左右子结点一个为空,一个非空,则将R的父结点中指向R的指针改为指向R的非空子 ...
- 使用二叉搜索树实现一个简单的Map
之前看了刘新宇大大的<算法新解>有了点收获,闲来无事,便写了一个二叉搜索树实现的Map类. java的Map接口有很多不想要的方法,自己定义了一个 public interface IMa ...
- 数据结构---二叉搜索树BST实现
1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...
随机推荐
- Part2-HttpClient官方教程-Chapter7-高级主题(Advanced topics) (HTTP Caching)
原文链接 7.1 自定义客户端连接 在某些情况下,为了能够处理非标准的.不兼容的行为,可能需要自定义HTTP消息通过网络传输的方式,而不是使用HTTP参数.例如,对于web爬虫,可能有必要迫使Http ...
- 10.异步SRAM的FPGA读写操作
异步SRAM:正如其名,不是与特定的时钟信号同步运行,而是根据输入信号的状态运行的.因为没有信号表明读取时已确定了有效数据,也没有信号表明写入时已接收到数据,所以,需要获取制造商的数据手册,根据时序图 ...
- HDU 5129 Yong Zheng's Death
题目链接:HDU-5129 题目大意为给一堆字符串,问由任意两个字符串的前缀子串(注意断句)能组成多少种不同的字符串. 思路是先用总方案数减去重复的方案数. 考虑对于一个字符串S,如图,假设S1,S2 ...
- codevs 1038 一元三次方程求解 NOIP2001提高组
题目链接:http://codevs.cn/problem/1038/ 题解: 嗯,exm?才知道二分隶属搜索专题…… 对-100到100枚举,按照题目中的提示,当当fi*fi+1<0时,二分深 ...
- C json实战引擎 一 , 实现解析部分
引言 以前可能是去年的去年,写了一个 c json 解析引擎用于一个统计实验数据项目开发中. 基本上能用. 去年在网上 看见了好多开源的c json引擎 .对其中一个比较标准的 cJSON 引擎 深入 ...
- App推广
一行业常见名词解释 开发商:也叫CP,即Content Provider内容提供商的英文首字母缩写. 发行商(运营商):即代理CP开发出来的产品. 渠道:拥有用户,能够进行流量分发的公司,即可成为渠道 ...
- IA32系统级架构总览(二)
系统级架构由寄存器.数据结构.指令组成,这些设计对基本的系统级别的操作提供了支持,比如:内存管理.终端与异常处理.任务管理.多进程控制等. 我们先来看一看寄存器与数据结构的总汇图:现在你可能看不懂,不 ...
- AC日记——[HNOI2008]玩具装箱toy bzoj 1010
1010 思路: 斜率优化DP: 跪烂大佬 代码: #include <bits/stdc++.h> using namespace std; #define maxn 50005 #de ...
- chattr命令的用法
chattr (配置文件隐藏属性)[root@www ~]# chattr [+-=][ASacdistu] 文件或目录名称选项与参数:+ :添加某一个特殊参数,其他原本存在参数则不动.- :移除某一 ...
- js对象替换键值名称
js对象替换键值名称 将obj中的id和name字段替换分别替换成为“@id”,“@name” 代码如下: let obj = [{id:,name:,name:"李四"}].ma ...