JAVA二叉查找树(搜索树)
自己通过java实现的二叉查找树,完整代码,有需求自取即可
包含,添加节点,删除节点(最复杂),查找节点三个主要的方法,有兴趣可以看一下
这里泛型Key继承了Comparable类用于比较键值大小
public class BinaryTree<Key extends Comparable<Key>,Value> {
private Node root;//根节点
private int N;//节点数
private class Node {
Key key;
Value value;
Node left;
Node right;
public Node() {
}
public Node(Key key, Value value, Node left, Node right) {
this.key = key;
this.value = value;
this.left = left;
this.right = right;
}
}
public BinaryTree() {
root = new Node(null, null, null, null);//初始化根节点
N = 0;//初始化节点数量
}
public void put(Key k, Value v) {
Node n = root;
//根节点赋值
if (n.value == null) {
n.key=k;
n.value=v;
N++;
return;
}
while (true) {
//key值相等,直接替换
if (k.compareTo(n.key) == 0) {
n.value = v;
return;
} else if (k.compareTo(n.key) > 0) {
//找右节点
if (n.right!=null)
n = n.right;
else if (n.right==null){
n.right=new Node(k,v,null,null);
N++;
return;
}
}
//找左节点
else if(k.compareTo(n.key) < 0){
if (n.left!=null)
n = n.right;
else if (n.left==null){
n.left=new Node(k,v,null,null);
N++;
return;
}
}
}
}
public Value get(Key k) {
Node n = root;
while (true){
if (n==null){
return null;
}
if (n.key.compareTo(k)==0){
return n.value;
}
else if (n.key.compareTo(k)>0){
n=n.left;
}
else
n=n.right;
}
}
public int getSize(){
return N;
}
public void delete(Key k){
Node n=root;
Node target=null;
Node target_father=null;
boolean target_is_left=true;
Node min_right=null;//右子树上最小的节点
Node min_right_father;//右子树上最小节点的父节点
if (root.key==null){
return;
}
//找到要删除的节点,及其父节点
while(n!=null){
if (k.compareTo(n.key)==0){
target=n;
break;
}
if (k.compareTo(n.key)>0){
target_father=n;
target_is_left=false;
n=n.right;
}
else if (k.compareTo(n.key)<0){
target_father=n;
target_is_left=true;
n=n.left;
}
}
//如果没找到就提前结束
if (n==null){
return;
}
//如果找到了,target即指向要删除的节点
//1、如果节点为叶子节点
if (target.left==null&&target.right==null){
//如果删除节点的父节点为空,即删除节点是根节点
if (target_father==null){
target.key=null;
target.value=null;
N--;
return;
}
//如果删除节点存在父节点
else if (target_father!=null){
//如果删除节点是其父节点的左节点
if (target_is_left){
target_father.left=null;
N--;
return;
}
//如果删除节点是其父节点的右节点
else {
target_father.right=null;
N--;
return;
}
}
}
//2、如果删除节点只有左子树
if (target.right==null&&target.left!=null){
//当删除节点是根节点
if (target_father==null) {
root=root.left;
N--;
return;
}
if (target_father!=null){
//如果删除节点是其父节点左子树
if (target_is_left){
target_father.left=target.left;
N--;
return;
}
else {
target_father.right=target.left;
N--;
return;
}
}
}
//3、如果删除节点只有右子树
if (target.right!=null&&target.left==null){
//当删除节点是根节点
if (target_father==null) {
root=root.right;
N--;
return;
}
if (target_father!=null){
//如果删除节点是其父节点左子树
if (target_is_left){
target_father.left=target.right;
N--;
return;
}
else {
target_father.right=target.right;
N--;
return;
}
}
}
//4、如果删除节点有左右子树
//找到其右子树上最小的节点(该节点一定不存在左子树)
if (target.left!=null&&target.right!=null){
min_right=target.right;
min_right_father=target;
while (min_right.left!=null){
min_right_father=min_right;
min_right=min_right.left;
}
//如果删除的节点是根节点
if (target_father==null){
//当用于替换的节点就是目标节点的右节点,即target的右节点没有左节点
if (min_right_father==target){
min_right.left=target.left;
root=min_right;
N--;
return;
}
//若不是
else {
min_right_father.left=min_right.right;
min_right.left=target.left;
min_right.right=target.right;
root=min_right;
N--;
return;
}
}
//若删除不是根节点
else {
//当用于替换的节点就是目标节点的右节点,即target的右节点没有左节点
if (min_right_father==target){
min_right.left=target.left;
if (target_is_left){
target_father.left=min_right;
}
else {
target_father.right=min_right;
}
N--;
return;
}
//若不是
else {
min_right_father.left=min_right.right;
min_right.left=target.left;
min_right.right=target.right;
if (target_is_left){
target_father.left=min_right;
}
else {
target_father.right=min_right;
}
N--;
return;
}
}
}
}
//二叉树的基础遍历
//获取二叉树前序遍历出的key值队列
public Queue<Key> getPreQueue(){
Queue<Key> keys = new Queue<Key>();
preErgodic(root,keys);
return keys;
}
//获取指定树中所有节点关键值,置于队列中(前序遍历)
private void preErgodic(Node node,Queue<Key> keys){
//如果传入节点为空,直接结束
if (node==null){
return;
}
keys.enqueue(node.key);
if (node.left!=null){
preErgodic(node.left,keys);
}
if (node.right!=null){
preErgodic(node.right,keys);
}
}
//获取二叉树中序遍历出的key值队列
public Queue<Key> getMinQueue(){
Queue<Key> keys = new Queue<Key>();
midErgodic(root,keys);
return keys;
}
//获取指定树中所有节点关键值,置于队列中(中序遍历)
private void midErgodic(Node node,Queue<Key> keys){
//如果传入节点为空,直接结束
if (node==null){
return;
}
if (node.left!=null){
preErgodic(node.left,keys);
}
keys.enqueue(node.key);
if (node.right!=null){
preErgodic(node.right,keys);
}
}
//获取二叉树后序遍历出的key值队列
public Queue<Key> getAfterQueue(){
Queue<Key> keys = new Queue<Key>();
afterErgodic(root,keys);
return keys;
}
//获取指定树中所有节点关键值,置于队列中(后序遍历)
private void afterErgodic(Node node,Queue<Key> keys){
//如果传入节点为空,直接结束
if (node==null){
return;
}
if (node.left!=null){
preErgodic(node.left,keys);
}
if (node.right!=null){
preErgodic(node.right,keys);
}
keys.enqueue(node.key);
}
//获取二叉树层序遍历出的key值队列
public Queue<Key> getLayerQueue(){
Queue<Key> keys = new Queue<Key>();
layerErgodic(root,keys);
return keys;
}
private void layerErgodic(Node node,Queue<Key> keys){
Queue<Node> queue = new Queue<>();
queue.enqueue(root);
while (queue.getSize()!=0){
Node n=queue.dequeue();
keys.enqueue(n.key);
if (n.left!=null){
queue.enqueue(n.left);
}
if (n.right!=null){
queue.enqueue(n.right);
}
}
}
//计算树的最大深度
public int getDepth(){
return maxDepth(root);
}
private int maxDepth(Node node){
if (node==null){
return 0;
}
//当前树的最大深度
int max=0;
//左子树的最大深度
int maxL=0;
//右子树最大深度
int maxR=0;
if (node.left!=null){
maxL=maxDepth(node.left);
}
if (node.right!=null){
maxR=maxDepth(node.right);
}
max=maxL>=maxR?maxL+1:maxR+1;
return max;//返回本树最大深度
}
}