定义
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。

性质
1,任意节点x,其左子树中的key不大于x.key,其右子树中的key不小于x.key。
2,不同的二叉搜索树可以代表同一组值的集合。
3,二叉搜索树的基本操作和树的高度成正比,所以如果是一棵完全二叉树的话最坏运行时间为Θ(lgn),但是若是一个n个节点连接成的线性树,那么最坏运行时间是Θ(n)。
4,根节点是唯一一个parent指针指向NIL节点的节点。
5,每一个节点至少包括key、left、right与parent四个属性,构建二叉搜索树时,必须存在针对key的比较算法。


简单实现(curd操作)

TreeNode.java

public class TreeNode {
private int data;
private TreeNode leftChild;
private TreeNode rightChild;
public TreeNode parent; public int getData() {
return data;
} public void setData(int data) {
this.data = data;
} public TreeNode getLeftChild() {
return leftChild;
} public void setLeftChild(TreeNode leftChild) {
this.leftChild = leftChild;
} public TreeNode getRightChild() {
return rightChild;
} public void setRightChild(TreeNode rightChild) {
this.rightChild = rightChild;
} public TreeNode getParent() {
return parent;
} public void setParent(TreeNode parent) {
this.parent = parent;
} public TreeNode(int data) {
super();
this.data = data;
} }

BinarySearchTree.java(不含main类,可以自己写main类)

public class BinarySearchTree {
private TreeNode root; //构造二叉搜索树
public TreeNode creatSearchBinaryTree(int data) {
TreeNode node = null;
TreeNode parent = null;
if (root == null) {
node = new TreeNode(data);
root = node;
}
node = root;
while (node != null) {
parent = node;
if (data > node.data) {
node = node.rightChild;
} else if (data < node.data) {
node = node.leftChild;
} else {
return node;
}
}
node = new TreeNode(data);
if (data < parent.data) {
parent.leftChild = node;
} else {
parent.rightChild = node;
}
node.parent = parent;
return node;
} //中序遍历
public void inOrder(TreeNode n) {
if (n != null) {
inOrder(n.getLeftChild());
System.out.print(n.data + " ");
inOrder(n.getRightChild());
}
} // 添加节点
public boolean insertNode(int data) {
TreeNode node = new TreeNode(data);
if (root == null) {
root = node;
return true;
}
TreeNode parent = root;
TreeNode current = root;
while (true) {
parent = current;
if (data == current.data) {
return true;
}
if (data < current.data) {
current = current.leftChild;
if (current == null) {
parent.leftChild = node;
return true;
}
} else {
current = current.rightChild;
if (current == null) {
parent.rightChild = node;
return true;
}
}
} } // 删除节点
public boolean deleteNode(int data) {
TreeNode current = root;
TreeNode parent = root;
boolean isLeftChild = true;
// 找到要删除的点,并记录该节点是否为左节点
while (current.data != data) {
parent = current;
if (data < current.data) {
isLeftChild = true;
current = current.leftChild;
} else {
isLeftChild = false;
current = current.rightChild;
}
if (current == null) {
return false;
}
}
// 如果删除节点为子节点
if (current.leftChild == null && current.rightChild == null) {
if (current == root) {
root = null;
} else {
if (isLeftChild == true) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
}
// 如果删除节点只有一个子节点
} else if ((current.leftChild != null && current.rightChild == null)
|| (current.leftChild == null && current.rightChild != null)) {
if (current.rightChild == null) {
if (root == current) {
root = current.leftChild;
} else {
if (isLeftChild == true) {
parent.leftChild = current.leftChild;
} else {
parent.rightChild = current.leftChild;
}
}
} else {
if (root == current) {
root = current.rightChild;
} else {
if (isLeftChild == true) {
parent.leftChild = current.rightChild;
} else {
parent.rightChild = current.rightChild;
}
}
}
// 如果删除节点同时有左右节点,找后继节点
} else if (current.leftChild != null && current.rightChild != null) {
TreeNode processer = processer(current);
if (current == root) {
root = processer;
} else {
if (isLeftChild == true) {
parent.leftChild = processer;
} else {
parent.rightChild = processer;
}
}
processer.leftChild = current.leftChild;
}
return true;
} //寻找后继节点
private TreeNode processer(TreeNode delNode) {
TreeNode parent = delNode;
TreeNode success = delNode;
TreeNode current = delNode.rightChild;
while (current != null) {
parent = current;
success = current;
current = current.leftChild;
}
if (success != delNode.rightChild) {
parent.leftChild = success.rightChild;
success.rightChild = delNode.rightChild;
}
return success;
} // 修改节点
public boolean updateNode(int oldData, int newData) {
boolean del = deleteNode(oldData);
insertNode(newData);
if (del == true) {
return true;
} else {
return false;
}
} // 查找节点
public TreeNode findNode(int data) {
TreeNode current = root;
while (current.data != data) {
if (data < current.data) {
current = current.leftChild;
} else {
current = current.rightChild;
}
if (current == null) {
return null;
}
}
return current;
}
}

Java数据结构——二叉搜索树的更多相关文章

  1. Java实现二叉搜索树

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...

  2. Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

    什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...

  3. Java创建二叉搜索树,实现搜索,插入,删除操作

    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...

  4. 数据结构-二叉搜索树(BST binary search tree)

    本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...

  5. 数据结构-二叉搜索树的js实现

    一.树的相关概念 1.基本概念 子树 一个子树由一个节点和它的后代构成. 节点的度 节点所拥有的子树的个数. 树的度 树中各节点度的最大值 节点的深度 节点的深度等于祖先节点的数量 树的高度 树的高度 ...

  6. 数据结构☞二叉搜索树BST

    二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...

  7. 基本数据结构 —— 二叉搜索树(C++实现)

    目录 什么是二叉搜索树 二叉搜索树如何储存数值 二叉搜索树的操作 插入一个数值 查询是否包含某个数值 删除某个数值 测试代码 参考资料 什么是二叉搜索树 二叉搜索树(英语:Binary Search ...

  8. Java实现二叉搜索树及相关操作

    package com.tree; import com.tree.BitNode; /** * * 二叉搜索树:一个节点的左子节点的关键字小于这个节点.右子节点的关键字大于或等于这个父节点 * * ...

  9. 数据结构---二叉搜索树BST实现

    1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...

随机推荐

  1. PHP imagecolorclosest - 取得与指定的颜色最接近的颜色的索引值

    imagecolorclosest — 取得与指定的颜色最接近的颜色的索引值.高佣联盟 www.cgewang.com 语法 int imagecolorclosest ( resource $ima ...

  2. 利用python进行数据分析PDF高清完整版免费下载|百度云盘|Python基础教程免费电子书

    点击获取提取码:hi2j 内容简介 [名人推荐] "科学计算和数据分析社区已经等待这本书很多年了:大量具体的实践建议,以及大量综合应用方法.本书在未来几年里肯定会成为Python领域中技术计 ...

  3. C# 实现线程的常用几种方式

    前言 在各个开发语言中,线程是避免不了的,或许通过表象看不出来,但是真的无处不在.就比如一个Web程序,平时或许只注重增删改查的开发,根本没有编写相关多线程的的代码,但是请求内部的时候,已经分配了对应 ...

  4. python6.2类的封装

    class Card(object): def __init__(self,num,pwd,ban): self.num=num#卡号 self.pwd=pwd#密码 self.__ban=ban#余 ...

  5. 解决:HBuilder X 未检测到手机或模拟器

    1.问题 我使用Android 9版本的手机,开发者选项已开启USB调试,但是HBuilderX未检测到手机或模拟器. 2.解决办法 1.找到HBuilderX安装目录下的D:\Archive\HBu ...

  6. Nginx介绍,安装,配置

    引言 为什么要学习Nginx 问题一: 客户端到底要将请求发送给哪台服务器? 问题二: 如果所有客户端的请求都发送给了服务器1,那另一台岂不是废了 问题三: 客户端发送的请求可能是申请动态资源的,也可 ...

  7. java中ThrealLocal的理解

    目录 java中threadlocal的理解 一.threadlocal的生命周期和ThreadLocalMap的生命周期 二.ThreadLocal的作用 三.threadlocal示例 四.Inh ...

  8. 【模式识别与机器学习】——4.3离散K-L变换

    全称:Karhunen-Loeve变换(卡洛南-洛伊变换) 前面讨论的特征选择是在一定准则下,从n个特征中选出k个来反映原有模式. 这种简单删掉某n-k个特征的做法并不十分理想,因为一般来说,原来的n ...

  9. 利用BeautifulSoup去除HTML指定标签和去除注释

    去除指定标签 from bs4 import BeautifulSoup #去除属性ul [s.extract() for s in soup("ul")] # 去除属性svg [ ...

  10. Golang并发编程基础

    硬件 内存 作为并发编程一个基础硬件知识储备,首先要说的就是内存了,总的来说在绝大多数情况下把内存的并发增删改查模型搞清楚了其他的基本上也是异曲同工之妙. 内存芯片--即我们所知道的内存颗粒,是一堆M ...