二叉排序树(Binary SortTree),又称为二叉查找树。它或者是一棵空树,或者是具有下列性质的二叉树。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空 ,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树。
定义节点
package BinaryTree;
//定义节点
public class Node {
int data;
Node lchild,rchild;
public int getData() {
return data;
}
public void setData(Integer data) {
this.data = data;
}
public Node getLchild() {
return lchild;
}
public void setLchild(Node lchild) {
this.lchild = lchild;
}
public Node getRchild() {
return rchild;
}
public void setRchild(Node rchild) {
this.rchild = rchild;
}
}
创建二叉排序树
package BinaryTree;
//创建二叉排序树
public class BinarySearchTree {
public static Node root; //定义根节点
public void addNode(int data){ //添加节点
Node node=new Node();
node.setData(data);
if (root==null){
root=node;
}
Node temp=root;
while (true){
if (data==temp.getData()){
break;
}
else if (data<temp.getData()){
if (temp.getLchild()==null){
temp.setLchild(node);
break;
}
else{
temp=temp.getLchild();
}
}
else {
if (temp.getRchild()==null){
temp.setRchild(node);
break;
}
else {
temp=temp.getRchild();
}
}
}
}
//中序遍历
public void LDR(Node root){
if (root.getLchild()!=null){
LDR(root.getLchild());
}
System.out.print(root.getData()+",");
if (root.getRchild()!=null){
LDR(root.getRchild());
}
}
//找指定节点(非根节点)的父节点
public Node SearchParent(Node parent, Node node){
if (node.getData()< parent.getData()){
if (node.getData()==parent.getLchild().getData()){
return parent;
}
else {
parent=parent.getLchild();
return SearchParent(parent,node);
}
}
else {
if (node.getData()==parent.getRchild().getData()){
return parent;
}
else {
parent=parent.getRchild();
return SearchParent(parent,node);
}
}
}
}
二叉排序树的查找、添加、删除
package BinaryTree;
public class SIDBST {
public static void main(String[] args) {
BinarySearchTree BST=new BinarySearchTree();
int[] a={62,88,58,47,35,73,51,99,37,93};
for (int temp:a) { //生成二叉排序树
BST.addNode(temp);
}
BST.LDR(BinarySearchTree.root);
System.out.println();
//查找
Node result=SearchBST(BinarySearchTree.root,62);
System.out.println(result.getData());
//插入
InsertBST(BST,29);
InsertBST(BST,36);
InsertBST(BST,49);
InsertBST(BST,48);
InsertBST(BST,50);
InsertBST(BST,56);
BST.LDR(BinarySearchTree.root);
System.out.println();
//删除
boolean result2=DeleteBTS(BinarySearchTree.root,47);
BST.LDR(BinarySearchTree.root);
//System.out.println(result2);
}
//实现二叉排序树的查找
public static Node SearchBST(Node root,int key){
if (root==null){
return null;
}
if (root.getData()==key){
return root;
}
else if(key<root.getData()){
return SearchBST(root.getLchild(),key);
}
else{
return SearchBST(root.getRchild(),key);
}
}
//实现二叉排序树的插入
public static boolean InsertBST(BinarySearchTree BST,int key){
if (SearchBST(BinarySearchTree.root,key)==null){ //查找不成功
BST.addNode(key);
return true;
}
else {
return false; //已有关键字相同的节点,不再插入
}
}
/*
删除节点
叶子节点:直接删除
仅有右或左子树的节点:将整个子树移动到删除节点的位置
左右子树都有:用左子树的最大值或右子树的最小值代替删除节点(即中序遍历的前驱或后继)
*/
public static boolean DeleteBTS(Node root,int key){ //key:要删除的值
if (SearchBST(root, key)==null){ //不存在该节点
return false;
}
else {
if (key==root.getData()){ //找到关键字等于key的元素
return Delete(root);
}
else if (key< root.getData()){
return DeleteBTS(root.getLchild(),key);
}
else {
return DeleteBTS(root.getRchild(),key);
}
}
}
public static boolean Delete(Node node){ //删除node
BinarySearchTree BTR=new BinarySearchTree();
if (node.getRchild()==null&&node.getLchild()==null){ //左右子树都为空
Node parent=BTR.SearchParent(BinarySearchTree.root,node);
if (parent.getLchild()==node){
parent.setLchild(null);
}
else {
parent.setRchild(null);
}
return true;
}
else if (node.getRchild()==null){ //右子树为空
Node parent=BTR.SearchParent(BinarySearchTree.root,node);
if (parent.getLchild()==node){
parent.setLchild(node.getLchild());
}
else {
parent.setRchild(node.getLchild());
}
return true;
}
else if (node.getLchild()==null){ //左子树为空
Node parent=BTR.SearchParent(BinarySearchTree.root,node);
if (parent.getLchild()==node){
parent.setLchild(node.getRchild());
}
else {
parent.setRchild(node.getRchild());
}
return true;
}
else { //左右子树都不为空
//使用左子树的最大值代替node,
Node s=node.lchild;
Node p=node;
while (s.getRchild()!=null){ //得到最大值
p=s; //保存最大值节点的父节点
s=s.getRchild();
}
node.setData(s.getData());
//删除左子树中的s
if (s.getLchild()==null){
p.setRchild(null);
}
else {
p.setRchild(s.getLchild());
}
return true;
}
}
}
查找的时间复杂度,取决于二叉树的深度,若二叉树比较平衡则时间复杂度为O(logn)