Java数据结构——二叉搜索树
定义
二叉查找树(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数据结构——二叉搜索树的更多相关文章
- Java实现二叉搜索树
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11406176.html 尝试一下用Java实现二叉搜索树/二叉查找树,记录自己的学习历程. 1 ...
- Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作
什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T ...
- Java创建二叉搜索树,实现搜索,插入,删除操作
Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...
- 数据结构-二叉搜索树(BST binary search tree)
本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来 ...
- 数据结构-二叉搜索树的js实现
一.树的相关概念 1.基本概念 子树 一个子树由一个节点和它的后代构成. 节点的度 节点所拥有的子树的个数. 树的度 树中各节点度的最大值 节点的深度 节点的深度等于祖先节点的数量 树的高度 树的高度 ...
- 数据结构☞二叉搜索树BST
二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它可以是一棵空树,也可以是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它 ...
- 基本数据结构 —— 二叉搜索树(C++实现)
目录 什么是二叉搜索树 二叉搜索树如何储存数值 二叉搜索树的操作 插入一个数值 查询是否包含某个数值 删除某个数值 测试代码 参考资料 什么是二叉搜索树 二叉搜索树(英语:Binary Search ...
- Java实现二叉搜索树及相关操作
package com.tree; import com.tree.BitNode; /** * * 二叉搜索树:一个节点的左子节点的关键字小于这个节点.右子节点的关键字大于或等于这个父节点 * * ...
- 数据结构---二叉搜索树BST实现
1. 二叉查找树 二叉查找树(Binary Search Tree),也称为二叉搜索树.有序二叉树(ordered binary tree)或排序二叉树(sorted binary tree),是指一 ...
随机推荐
- Python3.7安装pyaudio库报错问题及修复
本人今天在使用python编写语音相关项目是需要引用pyaudio库,结果发现引用失败,刚开始报错内容如下: 说让我升级pip,然后我就按照提示升级了pip,然后又再次尝试安装pyaudio库,然后还 ...
- Python List cmp()方法
描述 cmp() 方法用于比较两个列表的元素.高佣联盟 www.cgewang.com 语法 cmp()方法语法: cmp(list1, list2) 参数 list1 -- 比较的列表. list2 ...
- Redis 内存压缩原理
Redis 无疑是一个大量消耗内存的数据库,因此 Redis 引入了一些设计巧妙的数据结构进行内存压缩来减轻负担.ziplist.quicklist 以及 intset 是其中最常用最重要的压缩存储结 ...
- JS DOM笔记
js的组成 ECMAScript:JS的语法 DOM:页面文档对象模型 BOM:浏览器对象模型 web APIs 是浏览器提供的一套操作浏览器功能和页面元素的A ...
- 关于GPU你必须知道的基本知识
图形处理单元(或简称GPU)会负责处理从PC内部传送到所连接显示器的所有内容,无论你在玩游戏.编辑视频或只是盯着桌面的壁纸,所有显示器中显示的图像都是由GPU进行渲染的. 对普通用户来说,实际上不需要 ...
- C#LeetCode刷题-栈
栈篇 # 题名 刷题 通过率 难度 20 有效的括号 C#LeetCode刷题之#20-有效的括号(Valid Parentheses) 33.0% 简单 42 接雨水 35.6% 困难 71 简 ...
- 解决AndroidStudio 模拟器无网络连接
更新 注意 Win10 要在cmd下打开, 也就是地址栏打cmd能成功 转载地址 https://blog.csdn.net/Bibifeng/article/details/81317037 最近写 ...
- Nginx的Gzip功能
什么是HTTP压缩 有时候客户端和服务器之间会传输比较大的报文数据,这时候就占用较大的网络带宽和时长.为了节省带宽,加速报文的响应速速,可以将传输的报文数据先进行压缩,然后再进行传输. HTTP支持多 ...
- 复习 Array,重学 JavaScript
1 数组与对象 在 JavaScript 中,一个对象的键只能有两种类型:string 和 symbol.下文只考虑键为字符串的情况. 1.1 创建对象 在创建对象时,若对象的键为数字,或者由 字母+ ...
- 使用部分函数时并未include其所在头文件,但是能编译成功且能运行,为什么?
最近在看APUE,试了上面的一些例子,其中有个例子是使用getpid函数获取进程id,但是在我写demo时,并未引入其所在的头文件unistd.h,结果也能编译成功,也能运行,于是就琢磨下为啥. En ...