开门见山,首先来理解一下什么是二叉搜索树:也叫二叉排序树,是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。空树也是二叉搜索树。
简单的说,二叉搜索树就是一课二叉树,每个父节点都一定大于等于其左孩子且小于等于它的右孩子。
首先,创建一个节点类,Node,这个类需要有它左右孩子节点的引用,同时还应该有节点要存储的数据,为了简单起见,这里我只是用了一个index的整形数作为要保存的内容。
public class Node {
private int index;
private Node leftChild;
private Node rightChild;
public Node() {
}
public Node(int index) {
super();
this.index = index;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Node getLeftChild() {
return leftChild;
}
public void setLeftChild(Node leftChild) {
this.leftChild = leftChild;
}
public Node getRightChild() {
return rightChild;
}
public void setRightChild(Node rightChild) {
this.rightChild = rightChild;
}
}
接着,我们创建一个二叉树的类,BinaryTree,它只有一个根节点。里面主要有插入节点,查找节点的方法,删除节点的方法。
查找的过程:从根节点开始,根节点为当前节点,判断要查找的内容与当前节点的内容的大小关系,若查找值小于等于当前节点的内容值,往左子树方向查找,反之往右子树查找。改变当前节点的指向对象(指向要查找的那个方向的当前节点的孩子节点),重复上诉操作,直至找到节点或者到树的底部。
插入节点跟查找节点类似,用同样的方式找到要插入的节点的恰当的插入位置,把节点插入(即使上一级的节点的左/右孩子节点指向该要插入的节点)
删除节点的操作:分为三种情况,第一:该节点是叶子节点,找出来直接删除即刻;第二:该节点有一个孩子节点,找出节点,删除节点并让其父节点的左/右孩子节点引用指向删除的节点的孩子节点。第三:该节点有两个孩子节点,找出节点,然后找到该节点的直接后继节点(即中序遍历时,紧跟在这个节点后面的那个节点),并用这个节点代替删除的节点
public class BinaryTree {
private Node root;
public BinaryTree() {
}
public BinaryTree(Node root) {
this.root = root;
}
public Node getRoot() {
return root;
}
public void setRoot(Node root) {
this.root = root;
}
/**
* 寻找节点
*
* @param node
*/
public Node find(int index) {
if (this.root.getIndex() == index) {
return this.root;
}
Node current = this.root;
while (current != null) {
int temp_index = current.getIndex();
// 判断查询方向
if (temp_index >= index) {// 左子树
current = current.getLeftChild();
} else {
current = current.getRightChild();
}
// 判断是否匹配当前节点
if (current != null && current.getIndex() == index) {// 匹配则返回
return current;
}
}
return null;
}
/**
* 找到要找的节点的父节点
*
* @param index
* @return
*/
private Node findParent(int index) {
if (this.root.getIndex() == index) {
return this.root;
}
Node current = this.root;
Node parent = null;
while (current != null) {
parent = current;
int temp_index = current.getIndex();
// 判断查询方向
if (temp_index >= index) {// 左子树
current = current.getLeftChild();
} else {
current = current.getRightChild();
}
// 判断是否匹配当前节点
if (current != null && current.getIndex() == index) {// 匹配则返回
return parent;
}
}
return null;
}
/**
* 删除节点
*
* @param node
*/
public void delete(Node node) {
int index = node.getIndex();
Node target = find(index);
if (target == null) {
System.out.println("节点不存在");
return;
}
// 取得目标节点的父节点
Node parent = this.findParent(index);
// 目标节点左孩子
Node left_temp = target.getLeftChild();
// 目标节点右孩子
Node right_temp = target.getRightChild();
if (target.getLeftChild() != null && target.getRightChild() != null) {// 有两个孩子节点
// 目标节点直接左孩子
Node direct_leftChild = left_temp;
// 目标节点直接左孩子的父节点
Node direct_leftChild_p = target;
// 找到目标节点的直接左孩子节点以及记录该孩子节点的父节点
while (direct_leftChild.getLeftChild() != null) {
direct_leftChild_p = direct_leftChild;
direct_leftChild = direct_leftChild.getLeftChild();
}
// 执行删除操作
target = null;
if (parent.getLeftChild().getIndex() == index) {
parent.setLeftChild(direct_leftChild);
}
if (parent.getRightChild().getIndex() == index) {
parent.setRightChild(direct_leftChild);
}
if (direct_leftChild_p.getRightChild() != null) {
direct_leftChild.setRightChild(direct_leftChild_p
.getRightChild());
}
} else {// 节点是叶子节点或者只有一个子节点的情况
target = null;
// 判断被删除的节点是其父节点的哪个孩子
if (parent.getLeftChild().getIndex() == index) {// 左孩子
// 从新给左孩子设值(为了满足有单个孩子的情况,做了左右孩子值是否为空的判断)
parent.setLeftChild(left_temp == null ? right_temp : left_temp);
}
if (parent.getRightChild().getIndex() == index) {// 右孩子
// 同上
parent.setRightChild(right_temp == null ? left_temp
: right_temp);
}
}
}
/**
* 添加节点
*
* @param node
*/
public void insert(Node node) {
if (this.root == null) {// 根节点不存在
this.root = node;
} else {
Node current = this.root;
while (true) {
Node temp = null;
if (current.getIndex() > node.getIndex()) {// 左子树
temp = current.getLeftChild();
if (temp == null) {
current.setLeftChild(node);
return;
}
} else {
temp = current.getRightChild();
if (temp == null) {
current.setRightChild(node);
return;
}
}
current = temp;
}
}
}
public void print() {
inorder_traversal(this.root, 1);// 中序遍历的结果是一个有序的序列
}
/**
* 先序遍历
*
* @param node
* @param level
*/
private void preorder_traversal(Node node, int level) {// 先序遍历
for (int i = 0; i < level; i++) {
System.out.print("-");
}
System.out.println(node.getIndex());
int lev = level + 1;
if (node.getLeftChild() != null) {
preorder_traversal(node.getLeftChild(), lev);
}
if (node.getRightChild() != null) {
inorder_traversal(node.getRightChild(), lev);
}
}
/**
* 中序遍历
*
* @param node
* @param level
*/
private void inorder_traversal(Node node, int level) {// 中序遍历
int lev = level + 1;
if (node.getLeftChild() != null) {
inorder_traversal(node.getLeftChild(), lev);
}
for (int i = 0; i < level; i++) {
System.out.print("-");
}
System.out.println(node.getIndex());
if (node.getRightChild() != null) {
inorder_traversal(node.getRightChild(), lev);
}
}
/**
* 后序遍历
*
* @param node
* @param level
*/
private void postorder_traversal(Node node, int level) {// 后序遍历
int lev = level + 1;
if (node.getLeftChild() != null) {
postorder_traversal(node.getLeftChild(), lev);
}
if (node.getRightChild() != null) {
postorder_traversal(node.getRightChild(), lev);
}
for (int i = 0; i < level; i++) {
System.out.print("-");
}
System.out.println(node.getIndex());
}
}
分享到:
相关推荐
二叉排序树(Binary Sort Tree,BST),也称为二叉搜索树,是一种特殊的二叉树数据结构,它的每个节点都包含一个键(key)、一个关联的值、一个指向左子节点的指针和一个指向右子节点的指针。在二叉排序树中,对于...
这段代码展示了构建一个基本的二叉搜索树(Binary Search Tree, BST)的实现。二叉搜索树是一种特殊的二叉树,其中每个节点的值大于其左子树中所有节点的值,并且小于其右子树中所有节点的值。这种数据结构在查找、...
Java 实现二叉搜索树功能 二叉搜索树是一种特殊的二叉树,它的每个节点都含有一个Comparable的键值,且所有的键值都是唯一的,节点的键值也可以是基本类型,如int、long等,也可以是自定义的对象类型,只要实现了...
Java 创建二叉搜索树、实现搜索、插入、删除的操作实例 Java 创建二叉搜索树是指通过 Java 语言实现一个二叉搜索树数据结构,该树具有查找、插入、删除等操作的功能。二叉搜索树是一种特殊的二叉树,每个节点的值...
以下是Java实现二叉搜索树的查找、插入、删除和遍历的关键点: 1. **查找节点**: - 查找操作基于二叉搜索树的性质,从根节点开始,如果目标键值小于当前节点的键值,就向左子树移动;如果目标键值大于当前节点的...
`BST.java`很可能是二叉搜索树的实现,`TreeDoc.java`可能包含了关于数据结构或树操作的文档,而`BSTMain.java`应该是主程序,用于测试和展示二叉搜索树的功能。 在`BST.java`中,二叉搜索树的节点可能包含以下属性...
二叉排序树(Binary Sort Tree,也称为二叉搜索树),是数据结构中的一种特殊类型树,它具有以下特性:对于任意一个节点,其左子树中的所有节点的值都小于该节点的值,而右子树中的所有节点的值都大于该节点的值。...
在Java中实现二叉排序树,我们需要定义一个Node类来表示树的节点,包含键值、左子节点和右子节点。然后创建一个BST类,包含插入、查找和删除等基本操作。以下是一个简单的Java实现: ```java public class Node { ...
在Java中实现二叉搜索树,通常会定义一个`Node`类来表示树的节点,包含键、值、左子节点和右子节点等属性。接着,可以创建一个`BinarySearchTree`类,其中包含插入、查找和删除等方法。以下是一个简单的二叉搜索树的...
在Java中实现二叉搜索树,通常会定义一个名为`Node`的类来表示树的节点,包含键、值以及指向左右子节点的引用。接下来,我们创建一个名为`BinarySearchTree`的类,它包含了对树进行操作的主要方法,如插入、查找和...
其次,二叉平衡树(AVL树)是最早被提出的自平衡二叉搜索树,由G. M. Adelson-Velsky和E. M. Landis于1962年提出。AVL树要求每个节点的两个子树的高度差不超过1,以确保树的高度保持在log2(n+1)的范围内。为了维持这...
二叉查找树的实现。包括树的平衡以及树节点的删除。以及树的广度优先遍历,深度优先遍历。
二叉搜索树(Binary Search Tree, BST)是一种特殊的二叉树结构,其每个节点的值都大于左子树中所有节点的值,...这个转换过程对于理解和实现二叉搜索树到链表的转换具有重要意义,有助于提升对数据结构和算法的理解。
在JAVA中,构建二叉搜索树通常需要定义一个Node类来表示树的节点,节点通常包含一个键值(key)、一个指向左子节点的引用和一个指向右子节点的引用。例如: ```java public class Node { int key; Node left, ...
本文将详细解释如何将有序数组转换为二叉搜索树,包括问题描述、解题思路、Java 和 Python 实现代码以及时间和空间复杂度分析。 问题描述 给定一个整数数组 nums,其中元素已经按升序进行了排序,请将其转换为一棵...
C、C++和Java实现二叉查找树时,通常会定义一个结构体(或类)来表示树节点,包括键值、指向左右子节点的指针以及可能的额外信息。对于C++和Java,还可以使用面向对象的方式,定义一个类来封装插入、查找和删除的...
为了优化这种情况,可以使用自平衡二叉搜索树,如AVL树和红黑树,它们在任何情况下都能保证较好的性能。 以上就是关于Java实现二叉排序树的基本介绍,具体实现可以参考提供的`BinarySortTree.java`文件。在实际应用...
在Java中实现二叉搜索树,我们需要定义一个`Node`类来表示树的节点,通常包括键、值、左子节点和右子节点。接着,我们需要一个`BinarySearchTree`类来操作这些节点,包含插入、查找、删除等基本操作。 例如,在`src...
在Java中,查询二叉搜索树的最大元素和最小元素可以通过递归的方式实现。下面是查询二叉搜索树的最小节点和最大节点的方法: 1.1 查询二分搜索树的最小节点 public E minimum() { if (size == 0) { throw new ...