java实现二叉排序树

news/2024/11/9 11:04:36

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

/*
 * 二叉查找树的java实现,包涵构造二叉查找树和对二叉查找树的一系列操作
 * @version 1.0 2012/4/9
 * @author akon
 */
package com.akon405.www;

public class BSTree {
	BSTreeNode rootNode;//创建根节点
	//创建二叉查找树
	public void createBSTree(int[] A){
		rootNode=new BSTreeNode(A[0],null,null);//初始化根节点
		
		for(int i=1;i<A.length;i++){//逐个取出数组A中的元素用来构造二叉查找树
			BSTreeNode tmpNode=rootNode;
			while(true){
				if(tmpNode.data>=A[i]){//小于等于根节点
					if(tmpNode.left==null){//如果左孩子为空,这把当前数组元素插入到左孩子节点的位置
						tmpNode.left=new BSTreeNode(A[i],null,null);
						break;
					}
					tmpNode=tmpNode.left;//如果不为空的话,则把左孩子节点用来和当前数组元素作比较
				}else{//大于根节点
					if(tmpNode.right==null){//如果右孩子为空,这把当前数组元素插入到左孩子节点的位置
						tmpNode.right=new BSTreeNode(A[i],null,null);
						break;
					}
					tmpNode=tmpNode.right;//如果不为空的话,则把右孩子节点用来和当前数组元素作比较
				}
				}
			}
		
	}
	//中序遍历二叉查找树(中序遍历之后便可以排序成功)
	public void inOrderBSTree(BSTreeNode x){
		if(x!=null){
			inOrderBSTree(x.left);//先遍历左子树
			System.out.print(x.data+",");//打印中间节点
			inOrderBSTree(x.right);//最后遍历右子树
		}
	}
	//查询二叉排序树--递归算法
	public BSTreeNode searchBSTree1(BSTreeNode x,BSTreeNode k){
		if(x==null||k.data==x.data){
			return x;//返回查询到的节点
		}
		if(k.data<x.data){//如果k小于当前节点的数据域
			return searchBSTree1(x.left,k);//从左孩子节点继续遍历
		}else{//如果k大于当前节点的数据域
			return searchBSTree1(x.right,k);//从右孩子节点继续遍历
		}
	}
	//查询二叉排序树--非递归算法
	public BSTreeNode searchBSTree2(BSTreeNode x,BSTreeNode k){
		while(x!=null&&k.data!=x.data){
			if(x.data>k.data){
				x=x.left;//从左孩子节点继续遍历
			}else{
				x=x.right;//从右孩子节点继续遍历
			}
		}
		return x;
	}
	//查找二叉查找树的最小节点
	public BSTreeNode searchMinNode(BSTreeNode x){
		while(x.left!=null){
			x=x.left;
		}
		return x;
	}
	//查找二叉查找树的最大节点
	public BSTreeNode searchMaxNode(BSTreeNode x){
		while(x.right!=null){
			x=x.right;
		}
		return x;
	}
	//插入节点进入二叉查找树
	public void insert(BSTreeNode k){
		BSTreeNode r=rootNode;
		BSTreeNode p,q=null;
		p=r;
		while(p!=null){//while语句可以找到k节点所要插入的位置的父亲节点q
			q=p;
			if(p.data>k.data){
				p=p.left;
			}else{
				p=p.right;
			}
		}
		if(q==null){//二叉查找树为空树的情况下,直接插入到根节点,这里的q为已知的k的父亲节点
			r.data=k.data;
		}else if(q.data>k.data){//插入到父亲节点q的左边
			q.left=k;
		}else{//插入到父亲节点q的右边
			q.right=k;
		}
	}
	//删除二叉查找树中指定的节点
	public void delete(BSTreeNode k){//分三种情况删除
		if(k.left==null&&k.right==null){//第一种情况--没有子节点的情况下
			BSTreeNode p=parent(k);
			if(p.left==k){//其为父亲节点的左孩子
				p.left=null;
			}else if(p.right==k){//其为父亲节点的右孩子
				p.right=null;
			}
		}else if(k.left!=null&&k.right!=null){//第二种情况--有两个孩子节点的情况下
			BSTreeNode s=successor(k);//k的后继节点
			delete(s);
			k.data=s.data;
		}else{//第三种情况--只有一个孩子节点的情况下
			BSTreeNode p=parent(k);
			if(p.left==k){
				if(k.left!=null){
					p.left=k.left;
				}else{
					p.left=k.right;
				}
			}else if(p.right==k){
				if(k.left!=null){
					p.right=k.left;
				}else{
					p.right=k.right;
				}
			}
			
		}
	}
	//查找节点的前驱节点
	public BSTreeNode predecessor(BSTreeNode k){
		if(k.left!=null){
			return searchMaxNode(k.left);//左子树的最大值
		}
		BSTreeNode y=parent(k);
		while(y!=null&&k==y.left){//向上找到最近的一个节点,其父亲节点的右子树包涵了当前节点或者其父亲节点为空
			k=y;
			y=parent(y);
		}
		return y;
	}
	//查找节点的后继节点
	public BSTreeNode successor(BSTreeNode k){
		if(k.right!=null){
			return searchMinNode(k.right);//右子树的最小值
		}
		BSTreeNode y=parent(k);
		while(y!=null&&k==y.right){//向上找到最近的一个节点,其父亲节点的左子树包涵了当前节点或者其父亲节点为空
			k=y;
			y=parent(y);
		}
		return y;
	}
	//求出父亲节点,在定义节点类BSTreeNode的时候,没有申明父亲节点,所以这里专门用parent用来输出父亲节点(主要是不想修改代码了,就在这里加一个parent函数吧)
	public BSTreeNode parent(BSTreeNode k){
		BSTreeNode p=rootNode;
		BSTreeNode tmp=null;
		while(p!=null&&p.data!=k.data){//最后的p为p。data等于k.data的节点,tmp为p的父亲节点
			if(p.data>k.data){
				tmp=p;//临时存放父亲节点
				p=p.left;
			}else{
				tmp=p;//临时存放父亲节点
				p=p.right;
			}
		}
		return tmp;
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] A={23,12,43,2,87,54};
		BSTreeNode searchNode1=null;//递归查找到的结果
		BSTreeNode searchNode2=null;//非递归查找到的结果
		BSTreeNode searchMinNode=null;//最小节点
		BSTreeNode searchMaxNode=null;//最大节点
		BSTreeNode k=null,l=null,p=null,q=null,m=null,n=null;//申明6个节点k,l,p,q,m,n
		
		System.out.print("打印出数组A中的元素");
		for(int i=0;i<A.length;i++)
		System.out.print(A[i]+",");
		
		BSTree bs=new BSTree();
		
		bs.createBSTree(A);//创建二叉查找树
		
		System.out.println();
		System.out.print("中序遍历构造的二叉查找树:");
		bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树
		
		k=new BSTreeNode(23,null,null);//初始化一节点k,其data为null,左右孩子为null
		l=new BSTreeNode(17,null,null);//初始化一节点l,其data为null,左右孩子为null
		q=new BSTreeNode(12,null,null);//初始化一节点q,其data为null,左右孩子为null
		m=bs.searchBSTree2(bs.rootNode, k);//从二叉查找树里面查找一个节点,其m.data为k.data(这个m节点在后面用来测试程序)
		searchNode1=bs.searchBSTree1(bs.rootNode,k);//查询二叉查找树----递归算法
		searchNode2=bs.searchBSTree2(bs.rootNode,k);//查询二叉查找树----递归算法
		
		System.out.println("");
		System.out.println("递归算法--查找节点域:"+searchNode1.data+"左孩子:"+searchNode1.left.data+"右孩子:"+"查找节点域:"+searchNode1.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常
		System.out.println("非递归算法--查找节点域:"+searchNode2.data+"左孩子:"+searchNode2.left.data+"右孩子:"+"查找节点域:"+searchNode2.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常
		
		searchMinNode=bs.searchMinNode(bs.rootNode);//找到最小节点
		searchMaxNode=bs.searchMaxNode(bs.rootNode);//找到最大节点
		
		System.out.println("最小节点:"+searchMinNode.data);
		System.out.println("最大节点:"+searchMaxNode.data);
		
		bs.insert(l);//把l节点插入到二叉查找树中
		
		System.out.print("插入l节点(l的data为17)之后的二叉查找树的中序遍历结果:");
		bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树
				
		p=bs.parent(q);//取q节点的父亲节点
		
		System.out.println("");
		System.out.println("q的父亲节点(q的data为12):"+p.data+"左孩子:"+p.left.data+"右孩子:"+"查找节点域:"+p.right.data);//这里的左孩子或者右孩子节点可能打印为空,会出现null异常
		
		bs.delete(l);
		System.out.print("删除l节点(l的data为17)之后的二叉查找树的中序遍历结果:");
		bs.inOrderBSTree(bs.rootNode);//中序遍历二叉查找树
		
		n=bs.successor(m);
		System.out.println("");
		System.out.println("K的后继节点(k的data为23):"+n.data);
		
		n=bs.predecessor(m);
		System.out.println("K的前驱节点(k的data为23):"+n.data);
	}

}

//二叉查找树的节点类
class BSTreeNode{
	int data;//数据域
	BSTreeNode right;//左孩子
	BSTreeNode left;//右孩子
	//构造二叉查找树的节点
	public  BSTreeNode(int data,BSTreeNode right,BSTreeNode left){
		this.data=data;
		this.right=right;
		this.left=left;
	}

}

转载于:https://my.oschina.net/rouchongzi/blog/127749


http://www.niftyadmin.cn/n/639966.html

相关文章

HElib-2 向量内积

本文翻译自&#xff1a; https://mshcruz.wordpress.com/2016/09/27/scalar-product-using-helib/ 假设输入两个向量u[1,2,3,4],v[1,2,3,4]u[1,2,3,4],v[1,2,3,4],目的是计算两个向量的内积。 以下介绍三种方式可以在密文下进行运算&#xff0c;首先假设已经初始化&#xff…

第九十二课.什么是多态

什么是java的多态&#xff1a; 多态分为两种1.编译时多态&#xff1a;方法的重载&#xff1b;2.运行时多态&#xff1a;JAVA运行时系统根据调用该方法的实例的类型来决定选择调用哪个方法则被称为运行时多态。&#xff08;我们平时说得多的事运行时多态&#xff0c;所以多态主…

前端周记20190211-20190215

1、静态公有方法 (function(){var privateVariable10;function privateFunction(){return false;}MyObjectfunction(){}MyObject.prototype.publicMethodfunction(){privateVariable;return this;} })(); var anew MyObject(); console.log(a.publicMethod()); MyObject在私有作…

windows下安装使用gmp

windows下的安装配置&#xff1a;https://blog.csdn.net/u012629110/article/details/51220727 使用&#xff1a; 添加头文件&#xff1a; #include <gmpxx.h> 编译必须链接相应的库&#xff1a; g mycxxprog.cc -lgmpxx -lgmp -o mycxxprog (1)gmp整数操作&#x…

dark gdk+visual c++2008在虚拟机中的运行问题

最近在开始学习做游戏&#xff0c;但是自己用的系统是ubuntu&#xff0c;所以就装了一个virtualbox,并且装了一个xp&#xff0c;于是就开始了游戏之路&#xff0c;但是我发现游戏之路是如此的坎坷&#xff0c;很多小问题&#xff0c;不过都能很快的解决&#xff0c;由于我用的是…

号码隐私保护,让用户数据更安全

常言道“出行靠滴滴&#xff0c;吃饭有饿了么”&#xff0c;在科技的时代&#xff0c;互联网平台赋予了生活更多的选择&#xff0c;一切正变得丰富、便捷。小雨淅淅沥沥地湿润着春天&#xff0c;如往常般打开手机&#xff0c;我突然发现一些APP悄然无息地有了些共同的变化&…

Wordpress博客安装异次元分享工具条的方法

异次元单篇文章顶部的分享工具条做的很美观&#xff0c;集成了新浪微博、腾讯微博、QQ空间、人人网等分享按钮&#xff0c;页面浏览数以及支付宝捐赠等功能。可惜的是没有分享出来&#xff0c;黑苹果博客分享高仿版&#xff0c;具体方法&#xff1a; 基于 eliteYang 的 Version…

第九十三课.向上转型

Java 转型问题其实并不复杂&#xff0c;只要记住一句话&#xff1a;父类引用指向子类对象。什么叫父类引用指向子类对象&#xff0c;父类定义的对象存放的子类的地址 向上转型&#xff1a;通俗地讲即是将子类对象转为父类对象。此处父类对象可以是接口 举个例子&#xff1a;有…