您的位置:首页 > 编程语言 > Java开发

二叉搜索树的实现(包含插入、查找、遍历、删除等)【Java版】

2018-03-08 22:33 691 查看
package com.BinarySearchTree;

import java.util.LinkedList;

/**

*实现二分搜索树

*O(logn)

*适用于查找表(字典)

//定义树的结点
private class Node {
private Key  key; //键,相当于字典中的单词
private Value  value;//值,与键对应,相当于字典中单词的含义
private Node left; //左孩子结点
private Node right; //右孩子结点


//结点的构造函数
public Node(Key key,Value value) {
this.key=key;
this.value=value;
this.left=null;
this.right=null;
}


}

//树的根节点
private Node root;
//树中结点的个数
private int count;
//树中结点的总数


public int size() {
return count;
}
public boolean isEmpty() {
return count==0;
}


**

1.向二叉搜索树中插入新的节点,

//递归实现,也可以用非递归来实现
public void insert(Key key,Value value) {
root=insert(root,key, value);
}
//重写,向以node为根节点的二叉搜索树中插入新节点<key,value>,
//返回插入新节点后二叉搜索树的根
private Node insert(Node node,Key key,Value value) {
//处理递归到底的情况
if(node==null) {
count++;
return new Node(key, value);
}
//不支持重复元素,如果有重复,就更新
if(key==node.key) {
node.value=value;
}else if(node.key.compareTo(key)<0) {
node.right=insert(node.right, key, value);
}else {
node.left=insert(node.left, key, value);
}
return node;
}


2.在二叉搜索树中看是否包含键值为key的元素

public boolean contain(Key key) {
//递归实现,查找以root为根节点的树中是否包含key
return contain(root,key);
}
private boolean contain(Node node, Key key) {
//处理递归到底的情况
if(node==null)
return false;
if(key==node.key)
return true;
else if (node.key.compareTo(key)>0) {
return contain(node.left,key);
}else {
return contain(node.right, key);
}
}


3.在二叉搜索树中查找节点[找出key所对应的value]

public Value search(Key key) {
return search(root,key);
}
//在以node为根的二叉搜索树中查找key所对应的value
private Value search(Node node,Key key) {
if(node==null)
return null;

if(key==node.key)
return node.value;
else if(node.key.compareTo(key)>0)
return search(node.left,key);
else {
return search(node.right, key);
}
}


4.对二叉搜索树进行前序遍历【深度优先遍历】

public void preOrder() {
preOrder(root);
}
//对以node为根的二叉搜索树进行前序遍历
private void preOrder(Node node) {
if(node!=null) {
System.out.print(node.key+" ");
preOrder(node.left);
preOrder(node.right);
}
}


5.对二叉搜索树进行中序遍历【深度优先遍历】

public void inOrder() {
inOrder(root);
}
//对以node为根的二叉搜索树进行中序遍历
**//中序遍历即完成从小到大排序**
private void inOrder(Node node) {
if(node!=null) {
inOrder(node.left);
System.out.print(node.key+" ");
inOrder(node.right);
}
}


6.对二叉搜索树进行后序遍历【深度优先遍历】

public void postOrder() {
postOrder(root);
}
//对以node为根的二叉搜索树进行后序遍历
**//后序遍历可以释放二叉搜索树的空间**
private void postOrder(Node node) {
if(node!=null) {
postOrder(node.left);
postOrder(node.right);
System.out.print(node.key+" ");
}
}


7.对二叉搜索树进行层序遍历【广度优先遍历】

public void levelOrder() {
levelOrder(root);
}
//对以node为根的二叉搜索树进行层序遍历
public void levelOrder(Node node) {
LinkedList<Node> queue=new LinkedList<>();
queue.add(node);
while(!queue.isEmpty()) {
Node node2=queue.poll();
System.out.print(node2.key);
if(node2.left != null)
queue.add(node2.left);
if(node2.right!=null)
queue.add(node2.right);
}
}


8.寻找二叉搜索树的最小节点

public Node minNum() {
return minNum(root);
}
//寻找以node为根的二叉搜索树的最小节点
private Node minNum(Node node) {
if(node.left==null)
return node;
return minNum(node.left);
}


9.寻找二叉搜索树的最大值key

public Key maxNum() {
return maxNum(root);
}
//寻找以node为根的二叉搜索树的最大值
private Key maxNum(Node node) {
while(node.right!=null)
node=node.right;
return node.key;
}


10.删除二叉搜索树的最小值结点【要考虑最左子树还有右子树的情况】

public void removeMin() {
if(root!=null)
root=removeMin(root);
}
//删除以node为根的二叉搜索树的最小值,返回删除后新树的根结点【递归】
private Node removeMin(Node node) {
if(node.left==null) {
//包含了右子树为空的情况
count--;//节点数要减一
return node.right;
}
node.left=removeMin(node.left);
return node;
}


11.删除二叉搜索树的最大值结点【要考虑最右子树还有左子树的情况】

public void removeMax() {
if(root!=null)
root=removeMax(root);
}
//删除以node为根的二叉搜索树的最大值,返回新树的根结点
private Node removeMax(Node node) {
if(node.right==null) {
count--;
return node.left;
}
node.right=removeMax(node.right);
return node;
}


12.删除二叉搜索树中任意一个节点key

public void deleteNum(Key key) {
root=deleteNum(root,key);
}
//删除以node为根的二叉搜索树中,键值为key的节点
//返回删除后新二叉树的根
private Node deleteNum(Node node, Key key) {
//处理递归到底,未找到情况
if(node==null)
return null;
//在左子树中找到并删除
if(node.key.compareTo(key)>0) {
node.left=deleteNum(node.left,key);
}
//在右子树中找到并删除
else if(node.key.compareTo(key)<0) {
node.right=deleteNum(node.right, key);
}else {
//若左子树为空或者左右子树均为空
if(node.left==null) {
count--;
return node.right;
}
//若右子树为空
if(node.right==null) {
count--;
return node.left;
}
//若node的左右子树均不为空
//先找到右子树的最小值来作为要删除节点的后继
Node s1=minNum(node.right);
//新建一个节点,用来替换,以防和后面removeMin冲突
Node s=new Node(s1.key, s1.value);
count++;
//s的右子树是将s本身删除后的右子树
s.right=removeMin(node.right);
s.left=node.left;
count--;
return s;
}
return node;
}


测试

public static void main(String args[]) {
//不能用基本类型,HashMap对象的key、value值均可为null。
BinarySearchTree<Integer,String> bTree =new BinarySearchTree<>();
//插入数据
bTree.insert(7,"A");
bTree.insert(3, "C");
bTree.insert(4,"E");
bTree.insert(11,"r");
bTree.insert(23, "t");
bTree.insert(41,"e");
//包含和查找
System.out.println(bTree.contain(44));
System.out.println(bTree.search(11));
//深度优先遍历
bTree.preOrder();
bTree.inOrder();
bTree.postOrder();
//广度优先遍历【层序遍历】
bTree.levelOrder();
//寻找最小值和最大值
System.out.println(bTree.minNum().key);
System.out.println(bTree.maxNum());
//删除最大值
bTree.removeMax();
System.out.println(bTree.maxNum());
System.out.println(bTree.size());
//删除任意一个节点
bTree.deleteNum(11);
bTree.inOrder();
}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息