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

转载  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);
		}
	}
}

 

【图像去噪】论文复现:超分思想助力荧光显微图像自监督去噪!N2SR的Pytorch源码复现,图文详细教程跑通源码,框架结构原理示意图与代码对应,注释详细,补充三个实用功能代码! 论文题目:Noise2SR: Learning to Denoise from Super-Resolved Single Noisy Fluorescence Image —— Noise2SR:从超分辨率单噪声荧光图像中学习去噪【图像去噪】论文精读:Noise2SR: Learning to Denoise from Super-Resolved Single Noisy Fluorescence Image(N2SR)N2SR框架结构和原理都比较简单,创新点是加入超分,有很多类似的自监督框架; 阅读详情

相关推荐

一种高超声速飞行器弹道的仿真方法

设计并实现了一个高超声速飞行器弹道仿真算法,并应用到基于OSGEarth的态势中。

eyepeak的博客 6542

基于数组的二叉查找树 Binary Search Tree (Java实现)

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

weixin_33743880的博客 289

【Flink】状态编程: 订单超时告警

文章目录一、基础概念二、Flink状态编程1、支持的状态类型2、Managed Keyed State六种类型基本API状态的生命周期3、Managed Operator State三、案例:订单延迟告警统计1、需求描述2、需求分析3、数据与模型4、详细实现 一、基础概念 在Flink架构体系中,有状态计算可以说是Flink非常重要的特性之一。 有状态计算是指: 在程序计算过程中,在Flink...

一只皮皮熊 2864

基于二维数组的字典树的构建和查找

首先从根节点开始,根节点的编号为0,指针p指向根节点,那么ch[p]['a' - 'a']的值为1,代表从根节点出发衍生出的a节点的编号为1,由于ch[p][0]已经等于1,即a节点已经存在,那么我们将ch[p][0]赋值给指针p,那么p即为a节点的编号,由于ch[1][2]的值为0,说明a节点还未衍生出b节点,所以,我们新加入b节点,将ch[p][2]赋值为1即可。最后将p = ch[1][2],将p指向刚刚建立的b节点,b结点为ab的结尾,那么我们cnt[2]++代表ab这个单词出现了一次。

weixin_74084146的博客 631

AI赚钱新思路 利用RPA+KIMI实现小红书全自动制作发布(详细攻略)

我已经事先准备好了文案素材,现在就利用Kimi的智能,根据我们已有的文案来创作出新的文案吧。之前我写过一篇关于【:一个戴着用百元大钞制成的简约头饰的少女,她坐在小车里,手里拿着一叠港元,整个画面洋溢着现实主义动漫风格和治愈系的温暖气息。通过这篇文章,我们已经一步步地完成了小红书治愈系文案的创作、治愈系图片的生成,以及笔记的发布,实现了整个流程的自动化。不慌不忙,快乐常在 在繁忙的日常中,给自己的心灵留一片净土,感受内心深处的平静与安宁。接下来,我将展示如何使用影刀来编写自动化脚本,以生成治愈系的图文图片。

weixin_42172073的博客 3697

超详细的Burp Suite安装使用

‌Burp Suite是一个强大的Web应用安全测试工具,适用于网络安全专业人士进行自动化网络应用程序的安全测试。‌ 它提供了在Windows和Kali Linux上安装和激活Burp Suite Professional的简便步骤,帮助用户快速集成并启用强大的网络扫描和渗透测试功能。Burp Suite的特点包括易于安装、良好的兼容性、内置的自动化工具、优秀的用户体验以及详细的教程,使得无论是安全领域的新手还是经验丰富的专家,都能轻松上手并高效地进行安全测试。此外,Burp Suite还支持扩展功能的使用

Dreams°的博客 2643

二叉搜索树(数组实现)

二叉搜索树(数组实现)

m0_73604812的博客 612

MIKE水动力笔记7_实测数据与模型输出结果的拟合对比

上一博文【MIKE水动力笔记6】主要讲解如何自己制作实测数据的时间序列文件dfs0,而本博文讲解如何进行实测数据与模型输出结果的拟合对比。

晏长街的博客 1万+

打印二叉搜索树的叶子结点_带你玩转二叉查找树

通过之前文章,相信大家已经掌握了树这一重要的数据结构的基本概念以及很重要的二叉树。今天呢,我们就将在这个基础上,继续讲解非常非常常用的动态二叉树: 二叉查找树。树的基础知识, 如果忘了,可以参考下前文:且听风吟:我肝了三天,就是为了让你搞懂什么是树​zhuanlan.zhihu.com二叉查找树是个什么东西呢? 别急,下面我们将通过常规手段和非常规手段来带你了解一下。定义何谓二叉查找树?一种常见的...

weixin_42356475的博客 636

【软考高级架构】论文范文16——论分布式缓存架构设计及其应用

随着互联网业务的快速发展,高并发访问和海量数据处理对系统响应时间提出了极高要求,传统基于磁盘的数据库存储已难以满足毫秒级的性能需求。分布式缓存作为一种高性能、可扩展的数据存储中间件,能够有效减轻后端数据库压力、加速热点数据访问、提升系统吞吐量,已成为高并发系统架构中的核心组件。本文以笔者主导的某大型电商平台秒杀系统建设项目为案例,围绕分布式缓存架构设计展开论述。笔者担任系统架构师,主导了缓存选型、数据分片策略、缓存一致性方案、高可用架构及缓存穿透/雪崩/击穿防护机制的设计与落地。

qq837993702的博客 163

内存越界一定会导致程序崩溃吗?详解内存越界

本文详细解释了内存越界不一定导致内存越界的问题,全面介绍了C++内存越界的相关内容。

dvlinker的技术专栏 2万+

数据结构-二叉搜索树(Java实现)

二叉搜索树也叫做二叉排序树,如果中序遍历,这棵二叉搜索树的结果就是有序的,它是具备以下性质的二叉树:

cj13106811623的博客 1067

AUTOSAR进阶图解==>AUTOSAR_SWS_ECUStateManager

AUTOSAR ECU State Manager 摘要 AUTOSAR ECU状态管理器(EcuM)是Classic Platform 4.4.0规范中的核心模块,负责管理ECU的整个生命周期,包括启动、运行、关机和睡眠等状态转换。EcuM通过协调各基础软件模块的初始化过程,确保系统可靠运行。 主要功能包括: 启动管理 - 控制从硬件初始化到应用运行的完整启动序列 状态转换 - 管理RUN/POST_RUN/SHUTDOWN等状态切换 唤醒验证 - 区分真实与虚假唤醒事件 关机序列 - 确保安全关机保存关

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 2476

java数组查找文本_基于数组的二叉查找树 Binary Search Tree (Java实现)

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

weixin_36414025的博客 119

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【二叉查找树】04根据升序数组构造二叉查找树【Convert Sorted Array to Binary Search Tree】...

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个升序的数组,把他转换成一个高度平衡的二叉查找树 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++...

A201241302241的博客 191

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Leetcode 108 Convert Sorted Array to Binary Search Tree 有序数组构造平衡二叉查找树

给出一个有序数组(递增),使用该数组构造一个平衡二叉查找树。

(ง •̀_•́)ง 715

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

根据有序数组构造二叉查找树 Convert Sorted Array to Binary Search Tree

题目源自于leetcode。 题目:Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 思路:注意这里要的是平衡的BST。递归思想+二分查找法。把正中间的数作为树根,然后左和右两半段作为左子树和右子树。 代码: /** * Definit

LUCKYOJ 1610

LeetCode Convert Sorted Array to Binary Search Tree(有序数组转换为二叉查找树)

       这两天都有参加笔试,感触很深的就是觉着每天保持练习一些算法题对自己是很有益处的,首先编程题不至于没有思想,中等难度的题目思考一会也基本上可以搞定,更重要的是基础知识也得到了一定的巩固,要知道算法在不仅会体现在笔试里,在面试中也会是一些面试官考察应聘者编程能力的重要方式,所以希望大家也可以每天练习一定量的相关题目来培养及优化自己的解题思想,贵在坚持哦~       今天来跟大家分享一道...

gao__xue的博客 239

Convert Sorted Array to Binary Search Tree 将数组转换成二叉查找树

/**  * Definition for binary tree  * struct TreeNode {  *     int val;  *     TreeNode *left;  *     TreeNode *right;  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}  * };  */ cla

stophil的专栏 466

【LeetCode】将有序数组转化为二叉查找树:Convert Sorted Array to Binary Search Tree

class Solution { public: TreeNode* sortedArrayToBST(vector<int>& nums) { return sortedArrayToBST(nums, 0, nums.size() - 1); } TreeNode* sortedArrayToBST(vector<int>& nums, int begin, int end) { if(begin.

Arlingtonroad的博客 141

二叉查找树特性,优点,缺点

概述: 二叉排序树(Binary Sort Tree),又称二叉查找树(Binary Search Tree),亦称二叉搜索树.是数据结构中的一类.在一般情况下,查询效率比链表结构要高. 定义: 一棵二叉查找树是一棵二叉树,每个节点都含有一个Comparable的键(以及对应的值). 每个节点的键都大于左子树中任意节点的键而小于右子树中任意节点的键. 每个节点都有两个链接,左链接、右链接,分别指向自己的左子节点和右子节点,链接也可以指向null. 尽管链接指向的是节点,可以将每个链接看做指向了另一棵二

Strangerrainyday的博客 8685

树算法系列第二谈—— 二叉查找树与树的递归

二叉查找树与树的递归 引言 在上一篇文章中,主要介绍了二叉树的遍历相关以及相关联的算法这一篇也是系列的第二篇:二叉查找树相关的一些较为经典的力扣问题。在算法第四版中,对于树的介绍将其二叉查找树,与平衡查找树归于查询一章节中。对于平衡二叉树其查找的效率也是显而易见的,这里就不再过多展开。主要系列主线集中在对力扣的算法上面,具体的算法思想以及基础内容移步算法图书电子版。下面开始系列的问题的解决。 96...

weixin_44015043的博客 675

1064 Complete Binary Search Tree (30 分) 完全二叉查找树,用数组存放完全二叉树,用中序遍历构造二叉查找树

1064Complete Binary Search Tree(30分) A Binary Search Tree (BST) is recursively defined as a binary tree which has the following properties: The left subtree of a node contains only nodes with key...

ZXX_1999的博客 309

二叉排序树递归实现

public class BinarySortTreeDemo { public static void main(String[] args) { int[] array = {7, 3, 10, 12, 5, 1, 9}; BinaryTree binaryTree = new BinaryTree(); for (int i = 0;...

ytc958374686的博客 387

java-9. 判断整数序列是不是二元查找树的后序遍历结果

[code="java"] public class IsBinTreePostTraverse{ static boolean isBSTPostOrder(int[] a){ if(a==null){ return false; } /*1.只有一个结点时,肯定是查找树 *2.只有两个结点时,肯定是查找树。例如{5,6}对应的BST是 6 ...

代码说-Let code talk 172

数据结构-二叉树

根节点:没有父节点的节点 叶节点:没有子节点的节点 如G,H,I,J,K,L 兄弟节点:父节点相同的节点 如B,C ,D 父节点: A 节点就是 B 节点的父节点 子节点:B 节点是 A 节点的子节点 度:一个节点拥有的子树数称为节点的度(degree) 高度(Height) 深度(Depth) 层(Level) 满二叉树: 编号 2 的二叉树中,叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右两个子节点,这种二叉树就叫做满二叉树 完全二叉树: 编号 3 的二叉树中,叶子节点都在最底下***两

weixin_43866043的博客 141
上一篇: 正则表达式学习(一)
下一篇: 数据结构-堆实现
weixir123
博客等级 码龄16年 1粉丝 207原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值