7 Star 34 Fork 23

空無一悟/algorithms

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
BST.java 7.59 KB
一键复制 编辑 原始数据 按行查看 历史
空無一悟 提交于 2021-09-22 23:47 +08:00 . init
/***********************************************************
* @Description : 二分搜索树
* @author : 梁山广(Laing Shan Guang)
* @date : 2018/4/24 23:09
* @email : liangshanguang2@gmail.com
***********************************************************/
package Chapter5BinarySearchTree.Section5TraverseSection6LevelOrder;
import java.util.LinkedList;
/**
* @param <Key> 作为树的索引关键词,必须是可比较地,所以需要继承Comparable
* @param <Value> 不需要可比较
*/
public class BST<Key extends Comparable<Key>, Value> {
/**
* 节点类
*/
private class Node {
Key key;
Value value;
/**
* 左子节点
*/
Node left;
/**
* 右子节点
*/
Node right;
/**
* 构造函数
*/
Node(Key key, Value value) {
// key是唯一地,不能重复
this.key = key;
this.value = value;
this.left = null;
this.right = null;
}
}
/**
* 根节点
*/
private Node root;
/**
* 节点数
*/
private int count;
public BST() {
root = null;
count = 0;
}
public int size() {
return count;
}
public boolean isEmpty() {
return count == 0;
}
public void insert(Key key, Value value) {
root = insert(root, key, value);
}
public boolean contain(Key key) {
return contain(root, key);
}
public Value search(Key key) {
return search(root, key);
}
//***************************************************
//* 二分搜索树的辅助函数
//**************************************************
/**
* 向以node为根节点的二叉树搜索树种,插入节点(key,value)
* 返回插入新节点后的二叉搜索树的根
*/
private Node insert(Node node, Key key, Value value) {
// 处理最基本事件,即可以退出递归的事件
if (node == null) {
// 递归到没有子树了,就在这个位置插入。
count++; // 元素数先+1
// 把当前要插入的节点作为根节点返回,一层层递归后会跟新树路径上的节点关系地
return new Node(key, value);
}
if (key.compareTo(node.key) < 0) {
// 小于根节点的键,往左边子树插入
node.left = insert(node.left, key, value);
} else if (key.compareTo(node.key) > 0) {
// 大于根节点的键,往右边子树插入
node.right = insert(node.right, key, value);
} else {
// 如果key相等就直接更新(注意二叉搜索树的键是唯一地)
node.value = value;
}
return node;
}
/**
* 被递归调用来判断是否包含指定key的函数
*/
private boolean contain(Node node, Key key) {
// 递归退出条件.最后到达树底,下面没节点了(NULL),返回false
if (node == null) {
return false;
}
if (key.compareTo(node.key) > 0) {
// 大于就在右边找
return contain(node.right, key);
} else if (key.compareTo(node.key) < 0) {
// 小于就在左边找
return contain(node.left, key);
} else {
// 等于就返回true,代表找到含有这个key地节点了
return true;
}
}
/**
* 在以node为根的二叉搜索树种查找key对应的value
*/
private Value search(Node node, Key key) {
// 递归退出条件.最后到达树底,返回NULL
if (node == null) {
return null;
}
if (key.compareTo(node.key) > 0) {
// 大于就在右边找
return search(node.right, key);
} else if (key.compareTo(node.key) < 0) {
// 小于就在左边找
return search(node.left, key);
} else {
// 等于就返回true,代表找到含有这个key地节点了,返回Value的地址
return node.value;
}
}
/*****************************************************************************
* 前、中、后序遍历的私有函数:前中后序遍历的差别在于访问当前节点是在一开始、中间还是最后
* ***************************************************************************/
/**
* 前序遍历
*/
public void preOrder() {
preOrder(root);
}
/**
* 中序遍历
*/
public void inOrder() {
inOrder(root);
}
/**
* 后序遍历
*/
public void postOrder() {
postOrder(root);
}
/**
* 层序遍历(Level Order),又称广度优先遍历
*/
public void levelOrder() {
LinkedList<Node> queue = new LinkedList<>();
// 先推入根节点
queue.push(root);
while (!queue.isEmpty()) {
Node node = queue.remove();
System.out.println(node.key);
if (node.left != null) {
queue.push(node.left);
}
if (node.right != null) {
queue.push(node.right);
}
}
}
/*****************************************************************************
* 前、中、后序遍历的私有辅助函数:前中后序遍历的差别在于访问当前节点是在一开始、中间还是最后
* ***************************************************************************/
/**
* 对以node为根的二叉搜索树进行前序遍历
*/
private void preOrder(Node node) {
if (node != null) {
System.out.println(node.key);
preOrder(node.left);
preOrder(node.right);
}
}
/**
* 对以node为根的二叉搜索树进行中序遍历
*/
private void inOrder(Node node) {
if (node != null) {
inOrder(node.left);
System.out.println(node.key);
inOrder(node.right);
}
}
/**
* 对以node为根的二叉搜索树进行后序遍历
*/
private void postOrder(Node node) {
if (node != null) {
postOrder(node.left);
postOrder(node.right);
System.out.println(node.key);
}
}
public static void main(String[] args) {
BST<Integer, Integer> bst = new BST<Integer, Integer>();
// 取n个取值范围在[0...m)的随机整数放进二分搜索树中
int N = 10;
int M = 100;
for (int i = 0; i < N; i++) {
Integer key = (int) (Math.random() * M);
// 为了后续测试方便,这里value值取和key值一样
bst.insert(key, key);
System.out.print(key + " ");
}
System.out.println();
// 测试二分搜索树的size()
System.out.println("size: " + bst.size());
System.out.println();
// 测试二分搜索树的前序遍历 preOrder
System.out.println("preOrder: ");
bst.preOrder();
System.out.println();
// 测试二分搜索树的中序遍历 inOrder 中序排序可用于排序(升序)
System.out.println("inOrder: ");
bst.inOrder();
System.out.println();
// 测试二分搜索树的后序遍历 postOrder 后序遍历可用于释放二叉搜索树
System.out.println("postOrder: ");
bst.postOrder();
System.out.println();
// 层序遍历
System.out.println("levelOrder: ");
bst.levelOrder();
System.out.println();
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/lsgwr/algorithms.git
git@gitee.com:lsgwr/algorithms.git
lsgwr
algorithms
algorithms
master

搜索帮助