`

基于数组的二叉查找树 Binary Search Tree

    博客分类:
  • Java
 
阅读更多

转载  http://my.oschina.net/BreathL/blog/54734  

二叉查找树

     二叉查找树是一种支持动态查询的数据结构,所谓动态查寻结构:即在当数据集合内容发生改变时,集合内数据的排列组合不用重新构建。这样的数据结构在查询时需要不断变动的场景中是非常高效的,二叉查找树就是其中一个,并且它是SBT,AVL,红黑树的基础,一直有兴趣想要研究下。原理就不介绍了,可参考这个 。今天花了半天时间,自己完成了一个基于数组的Java实现。

实现的方法:INSERT、SEACH、DELETE

      先简单说明下这几个方法的实现原理:

 

SEARCH:

      查询方法的思路很简单,和二分查找相似,即从根节点开始查找,若待查找元素a小于根节点,则在该节点的左子树中继续查找,大于则去右子树中,等于便是找到了。

 

 

INSERT:

      插入方法,也是一个查询的过程,若根节点为空,则直接设置成跟节点,否则依如下方式与节点比较: 若小于节点值,将元素插入其左子树,若大于该节点值插入其右子树。若发现相等的则退出,算是排重。

DELETE:

      删除操作相对比较复杂,若要删除某一个节点 Z ,可能遇见三种情况: 
     一.    节点 Z 不包含任何子树;此时可直接删除,不影响数据的结构。
     二.    节点 Z  只有一个子子树,左子树或右子树;此时只需将 Z 的唯一的那个子树的根节点指向 Z 的父节点即可,此操作也不影响数据的。(但由于我是基于数组的,指针式通过数组的位置表示,所以某个节点指向变了,其所有子节点在数组中的位置都要变,不过好在这种变化是有规律的,我已在程序中注明。)
     三.     节点 Z 的左子树和右子树同时存在。这种情况最为复杂,首先找到 Z 左子树中值最大的节点,记为 H ,将代替 Z 在树种的位置,然后再以递归的方式删除节点 H.
 

 

package com.mycode.structures;

import java.util.Collection;

/**
 * 基于数组二叉查找树实现
 * @author Breath_L
 * @param <T>
 */
public class BSTree<T extends Comparable<T>> {
	private static final int DEFAULT_SIZE = 10;
	private T[] data;
	private Integer count;
	
	public Integer getCount(){
		return count;
	}
	
	public BSTree(int size){
		data = (T[]) new Object[size];
		count = 0;
	}
	
	public BSTree(){
		data = (T[]) new Object[DEFAULT_SIZE];
		count = 0;
	}
	
	/**
	 * 扩充容量
	 */
	private void expandSize(){
		T[] newDate = (T[]) new Object[data.length * 2];
		System.arraycopy(data, 0, newDate, 0, data.length);
		data = newDate;		
	}
	
	/**
	 * 判断二叉树中是否包含元素 one
	 * @param one
	 * @return 若找到了,返回该元素在数组中的位置,否则返回-1
	 */
	public int search(T one){
		if(data[0] == null){
			System.out.println("==> This BSTree is Empty!");
			return -1;
		}else{
			int index = 0;
			while(index < data.length && data[index] != null){
				int f = one.compareTo(data[index]);
				if(f == 0){                    //找到了返回其位置
					return index;
				}else if(f < 0){
					index = 2 * index + 1;
				}else{
					index = 2 * index + 2;
				}
			}
			return -1;
		}
	}
	
	/**
	 * 添加元素
	 * @param t
	 */
	public void add(T t){
		if(data[0] == null){
			data[0] = t;
			count++;
			return;
		}else{
			int index = 0;
			while(index < data.length){
				if(t.compareTo(data[index])<0){
					int left = 2 * index + 1;
					if(left >= data.length)
						expandSize();					
					if(data[left] == null){
						data[left] = t;
						break;
					}else{
						index = left;
					}
				}else if(t.compareTo(data[index]) > 0){
					int right = 2 * index + 2;
					if(right >= data.length)
						expandSize();
					if(data[right] == null){
						data[right] = t;
						break;
					}else{
						index = right;
					}
				}else{                        // 相同元素不处理,算是排重了
					break;
				}				
			}
		}
		count++;
	}
	
	public void addAll(Collection<T> all){
		for (T t:all){
			add(t);
		}
	}
	public void addAll(T[] all){
		for (T t:all){
			add(t);
		}
	}
	
	public void delete(T del){
		int del_index = this.search(del);
		if(del_index != -1){                    //等于-1 表示没有,便不做处理
			real_delete(del_index);
		}
	}
	
	/**
	 * 删除某个节点
	 * @param index:该节点在数组中的位置
	 * @return 
	 */
	private void real_delete(int index){
		int lc = 2*index + 1;
		int rc = 2*index + 2;
		if(data[lc] != null && data[rc] != null){        // 左子树、右子树同时存在的情况
			int left_max_child = findLeftMaxChild(index);
			data[index] = data[left_max_child];          //删除节点
			real_delete(left_max_child);                 //递归删除左子树中值最大的节点
		}else if(data[lc] == null && data[rc] == null){  // 都没有则直接删除
			data[index] = null;
		}else{ 
			if(data[lc] != null){
				replaceNodeWithChild(lc, lc-index);
			}else{
				replaceNodeWithChild(rc, rc-index);
			}
		}
	}
	
	/**
	 * 寻找某个节点的左子树中最大节点
	 * @param index 某个节点的位置
	 * @return 最大节点位置
	 */
	private int findLeftMaxChild(int index){
		int left = 2*index +1;
		int bigger = 2*left + 2;
		while( bigger < data.length && data[bigger] != null){			
			left = bigger;
			bigger = 2 * bigger + 2;			
		}
		return left;
	}
	
	/**
	 * 若子节点C替换了其父节点P,则C的所有子节点都需要被移动(由于数组的原因),distance为C和P在数组中位置之差。
	 * 其所有子节点在数组中移动的距离为 distance*(2^x),x为这些子节点与节点C的距离(相邻节点距离为1);
	 * @param node
	 * @param distance
	 */
	private void replaceNodeWithChild(int node, int distance){
		int left = 2*node+1;
		int right = 2*node+2;
		int current_distance = distance*2;                   //每次递归距离*2 
		if(data[left] != null){
			data[left - current_distance] = data[left];
			replaceNodeWithChild(left,current_distance);     //递归遍历下个节点
		}
		if(data[right] != null){
			data[right - current_distance] = data[right];
			replaceNodeWithChild(right,current_distance);
		}
	}
}

 

分享到:
评论

相关推荐

    最优二叉查找树

    在计算机科学中,最优二叉查找树(Optimal Binary Search Tree,简称OBST)是一种特殊的二叉查找树,其设计目标是在平均情况下提供最短的查找时间。与普通二叉查找树不同,最优二叉查找树的结构不是由插入顺序决定的...

    最优二叉查找树 动态规划法.cpp.rar

    最优二叉查找树(Optimal Binary Search Tree, OBST)是一种高效的检索数据结构,它根据键值分布的不同,自适应地调整树的形态以达到最小化查找时间的目的。在计算机科学中,动态规划(Dynamic Programming, DP)是...

    第六课_二分查找与二叉查找树.pdf

    二叉查找树(Binary Search Tree, BST)是另一种用于快速查找和插入的数据结构。二叉查找树的每个节点都包含一个键值和左、右两个子树。在二叉查找树中,左子树上的所有节点的键值都小于其根节点的键值,而右子树上...

    基于二叉排序树的排序查找应用C源码

    接下来,我们要讨论的核心是“二叉排序树”(Binary Sort Tree,BST)。二叉排序树是一种特殊的二叉树,其中每个节点的左子树只包含比它小的元素,右子树则包含比它大的元素。这种结构使得查找、插入和删除操作的...

    《数据结构与算法》-李春葆 实验报告-典型查找算法实践-二叉查找树实现查找

    这篇实验报告是关于《数据结构与算法》课程中的一次实验,主要关注的是二叉查找树(Binary Search Tree,简称BST)的实现及其在查找操作中的应用。二叉查找树是一种特殊的二叉树,它的每个节点都包含一个键值,且...

    最优二叉检索树(Optimal Search Tree)

    最优二叉检索树(Optimal Binary Search Tree, OBST),是一种特殊的二叉树结构,它旨在通过优化节点布局来降低查找数据时所需的平均成本。在构建最优二叉检索树的过程中,通常会考虑节点访问频率这一重要因素,以此...

    二叉排序树 平均查找长度的操作

    二叉排序树(Binary Sort Tree,BST),也称为二叉搜索树,是一种特殊的二叉树数据结构,它的每个节点都包含一个键值,且满足以下性质:对于任意节点,其左子树中的所有节点的键值都小于该节点的键值,而右子树中的...

    基于二叉排序树写的通讯录

    **二叉排序树(Binary Search Tree)的概念与特性** - **概念**:二叉排序树是一种特殊的二叉树,其中每个节点包含一个关键字,左子树中的所有节点的关键字均小于其父节点的关键字,右子树中的所有节点的关键字均...

    数据结构课程设计 二叉排序树与平衡二叉排序树

    在数据结构的学习中,二叉排序树(Binary Search Tree,BST)是一种常见的树形数据结构,它具有查找、插入和删除等操作的高效性。在这个课程设计中,我们将重点探讨如何利用二叉链表作为存储结构来实现二叉排序树,...

    二叉排序树查找

    根据提供的文件信息,本文将详细解释二叉排序树(Binary Search Tree, BST)的基本概念、构建过程、插入操作以及查找操作。二叉排序树是一种非常有用的动态数据结构,它不仅支持快速查找,还支持插入、删除等操作。 ...

    VC/C++实现二叉搜索树查找算法

    二叉搜索树(Binary Search Tree, BST)是计算机科学中一种重要的数据结构,它在处理大量数据时提供了高效的操作,如查找、插入和删除。在本主题中,我们将深入探讨如何使用VC/C++编程语言实现二叉搜索树的查找算法...

    数据结构课程设计二叉排序树的实现

    二叉排序树(Binary Search Tree, BST),又称二叉查找树或有序二叉树,是一种特殊的二叉树,其特点在于对于任意节点而言,其左子树中的所有节点的值均小于该节点的值,而右子树中的所有节点的值均大于该节点的值。...

    optimalBinarySeachTree.rar_binary search_build binary tree_searc

    最优二叉搜索树,又称为最优点缀树,是一种特殊的二叉查找树,它的每个结点都包含一个关键字,并且是有序排列的。这种树在搜索操作时能提供最小的平均查找时间。在构建最优二叉搜索树时,我们通常采用动态规划的方法...

    将升序数组转化为平衡二叉搜索树

    在计算机科学领域,二叉搜索树(Binary Search Tree, BST)是一种非常重要的数据结构,它能够有效地支持插入、删除、查找等操作。而平衡二叉搜索树(AVL树、红黑树等)则是进一步优化了传统二叉搜索树的结构,以保持树的...

    二叉链表和顺序表建二叉排序树

    在本篇文章中,我们将深入探讨如何利用二叉链表和顺序表两种不同的数据结构来构建二叉排序树(Binary Search Tree, BST),并通过具体示例来演示其创建、遍历以及查找性能分析的过程。 #### 二叉链表构建二叉排序树...

    二叉排序树 二叉排序树

    二叉排序树(Binary Search Tree,BST)是一种重要的数据结构,在计算机科学中有着广泛的应用。本文将基于给定的代码片段深入探讨二叉排序树的基本概念、性质、操作及其实现。 ### 一、二叉排序树的基本概念 二叉...

    java-leetcode题解之第108题将有序数组转换为二叉搜索树.zip

    这是一道关于数据结构与算法的题目,主要涉及到二叉搜索树(Binary Search Tree, BST)的概念以及如何通过已排序的数组来构建这种特定类型的树。下面,我们将深入探讨这个问题及其解决方案。 首先,二叉搜索树是一...

    8607 实现二叉排序树的各种算法.txt

    ### 二叉排序树(Binary Search Tree,BST) 二叉排序树是一种特殊的二叉树,其中每个节点的值都大于或等于其左子树中所有节点的值,并且小于或等于其右子树中所有节点的值。这种结构使得在树中查找、插入和删除...

    BST.rar_二叉查找

    **二叉查找树(Binary Search Tree,简称BST)**是一种自平衡的二叉搜索数据结构,它具有以下特性: 1. 每个节点都包含一个键(key)、一个关联的值、一个指向左子节点的引用和一个指向右子节点的引用。 2. 节点的...

Global site tag (gtag.js) - Google Analytics