二叉排序树平均查找长度

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉排序树平均查找长度相关的知识,希望对你有一定的参考价值。

参考技术A

二叉排序树平均查找长度为:ASL=∑(本层高度*本层元素结点个数)/结点总数。

二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树。

与次优二叉树相对,二叉排序树是一种动态树表。其特点是:树的结构通常不是一次生成的,而是在查找过程中,当树中不存在关键字等于给定值的结点时再进行插入。新插入的结点一定是一个新添加的叶子结点,并且是查找不成功时查找路径上访问的最后一个结点的左孩子或右孩子结点。

二叉排序树相关术语:

1、根节点:根节点是一个没有双亲结点的结点,一棵树中最多有一个根节点。

2、边:边表示从双亲结点到孩子结点的链接。

3、叶子结点:没有孩子结点的结点叫作叶子结点。

4、兄弟结点:拥有相同双亲结点的所有孩子结点叫作兄弟结点。

5、祖先结点:如果存在一条从根节点到结点q的路径,其结点p出现在这条路径上,那么就可以吧结点p叫作结点q的祖先结点,结点q也叫做p的子孙结点。

6、结点的大小:结点的大小是指子孙的个数,包括其自身。

Java实现二叉排序树的插入查找删除

 

 

import java.util.Random;

/**
 * 二叉排序树(又称二叉查找树)
 * (1)能够是一颗空树
 * (2)若左子树不空,则左子树上全部的结点的值均小于她的根节点的值
 * (3)若右子树不空,则右子树上全部的结点的值均大于她的根节点的值
 * (4)左、右子树也分别为二叉排序树
 * 
 * 
 * 性能分析:
 * 查找性能:
 * 		含有n个结点的二叉排序树的平均查找长度和树的形态有关。
 * 		(最坏情况)当先后插入的keyword有序时。构成的二叉排序树蜕变为单枝树。查找性能为O(n)
 * 		(最好情况)二叉排序树的形态和折半查找的判定树同样,其平均查找长度和log2(n)成正比
 * 
 * 
 * 插入、删除性能:
 * 		插入、删除操作间复杂度都O(log(n))级的。
 * 		即经过O(log(n))时间搜索到了需插入删除节点位置和删除节点的位置
 * 		经O(1)级的时间直接插入和删除
 * 		与顺序表相比。比序顺序表插入删除O(n)(查找时间O(log(n))移动节点时间O(n))要快
 * 		与无序顺序表插入时间O(1),删除时间O(n)相比,由于是有序的,所查找速度要快非常多
 * 
 * 
 * 
 * 作者:小菜鸟
 * 创建时间:2014-08-17
 * 
 */

public class BinarySortTree {

	private Node root = null;

	
	/**查找二叉排序树中是否有key值*/
	public boolean searchBST(int key){
		Node current = root;
		while(current != null){
			if(key == current.getValue())
				return true;
			else if(key < current.getValue())
				current = current.getLeft();
			else
				current = current.getRight();
		}
		return false;
	}
	
	
	/**向二叉排序树中插入结点*/
	public void insertBST(int key){
		Node p = root;
		/**记录查找结点的前一个结点*/
		Node prev = null;
		/**一直查找下去,直到到达满足条件的结点位置*/
		while(p != null){
			prev = p;
			if(key < p.getValue())
				p = p.getLeft();
			else if(key > p.getValue())
				p = p.getRight();
			else
				return;
		}
		/**prve是要安放结点的父节点,依据结点值得大小,放在对应的位置*/
		if(root == null)
			root = new Node(key);
		else if(key < prev.getValue())
			prev.setLeft(new Node(key));
		else prev.setRight(new Node(key));
	}
	
	
	
	/**
	 * 删除二叉排序树中的结点
	 * 分为三种情况:(删除结点为*p 。其父结点为*f)
	 * (1)要删除的*p结点是叶子结点,仅仅须要改动它的双亲结点的指针为空
	 * (2)若*p仅仅有左子树或者仅仅有右子树,直接让左子树/右子树取代*p
	 * (3)若*p既有左子树,又有右子树
	 * 		用p左子树中最大的那个值(即最右端S)取代P。删除s,重接其左子树
	 * */
	public void deleteBST(int key){
		deleteBST(root, key);
	}
	private boolean deleteBST(Node node, int key) {
		if(node == null) return false;
		else{
			if(key == node.getValue()){
				return delete(node);
			}
			else if(key < node.getValue()){
				return deleteBST(node.getLeft(), key);
			}
			else{
				return deleteBST(node.getRight(), key);
			}
		}
	}

	private boolean delete(Node node) {
		Node temp = null;
		/**右子树空,仅仅须要重接它的左子树
		 * 假设是叶子结点,在这里也把叶子结点删除了
		 * */
		if(node.getRight() == null){
			temp = node;
			node = node.getLeft();
		}
		/**左子树空, 重接它的右子树*/
		else if(node.getLeft() == null){
			temp = node;
			node = node.getRight();
		}
		/**左右子树均不为空*/
		else{
			temp = node;
			Node s = node;
			/**转向左子树,然后向右走到“尽头”*/
			s = s.getLeft();
			while(s.getRight() != null){
				temp = s;
				s = s.getRight();
			}
			node.setValue(s.getValue());
			if(temp != node){
				temp.setRight(s.getLeft());
			}
			else{
				temp.setLeft(s.getLeft());
			}
		}
		return true;
	}

	
	/**中序非递归遍历二叉树
	 * 获得有序序列
	 * */
	public void nrInOrderTraverse(){
		Stack<Node> stack = new Stack<Node>();
		Node node = root;
		while(node != null || !stack.isEmpty()){
			while(node != null){
				stack.push(node);
				node = node.getLeft();
			}
			node = stack.pop();
			System.out.println(node.getValue());
			node = node.getRight();
		}
	}
	
	public static void main(String[] args){
		BinarySortTree bst = new BinarySortTree();
		/**构建的二叉树没有同样元素*/
		int[] num = {4,7,2,1,10,6,9,3,8,11,2, 0, -2};
		for(int i = 0; i < num.length; i++){
			bst.insertBST(num[i]);
		}
		bst.nrInOrderTraverse();
		System.out.println(bst.searchBST(10));
		bst.deleteBST(2);
		bst.nrInOrderTraverse();
	}
	
	
	/**二叉树的结点定义*/
	public class Node{
		private int value;
		private Node left;
		private Node right;
		
		public Node(){
		}
		public Node(Node left, Node right, int value){
			this.left = left;
			this.right = right;
			this.value = value;
		}
		public Node(int value){
			this(null, null, value);
		}
		
		public Node getLeft(){
			return this.left;
		}
		public void setLeft(Node left){
			this.left = left;
		}
		public Node getRight(){
			return this.right;
		}
		public void setRight(Node right){
			this.right = right;
		}
		public int getValue(){
			return this.value;
		}
		public void setValue(int value){
			this.value = value;
		}
	}
	
}



 


以上是关于二叉排序树平均查找长度的主要内容,如果未能解决你的问题,请参考以下文章

查找有序表折半查找判定树二叉排序树3阶B-树

数据结构学习笔记——二叉排序树

数据结构学习笔记——二叉排序树

数据结构学习笔记——二叉排序树

Java实现二叉排序树的插入查找删除

查找--练习题