`

#每周一算法#二叉查找树

 
阅读更多

#每周一算法# 本周介绍一下二叉查找树,二叉查找树一般用的不是很多,但是它是平衡二叉树和红黑树的基础,所以还是要好好了解一下的。
首先说一下什么是二叉查找树:
二叉查找树是一种特殊的二叉树,特殊在哪呢?
1.对于树中的任意节点X,如果它的左子树不为空,则左子树中的所有节点的值均小于X的值。
2.对于树中的任意节点X,如果它的右子树不为空,则右子树中的所有节点的值均大于X的值。
3.二叉查找树的中序遍历是一个从小到大的有序序列。
如图这是一个二叉查找树:

 
下面这个不是二叉查找树,因为节点8是节点7的左子树,其值不能大于7:



 

 下面来看一下二叉查找树的一些基本操作:

1.插入操作:
  将新节点X插入到树T中,进行如下判断:
  1.如果T是空树,则X作为树T的根节点
  2.如果X的值小于根节点的值,则将X节点插入到左子树中,然后通过递归比较左子树的节点,直到插入到合适的位置
  3.如果X的值大于根节点的值,则将X节点插入到右子树中,然后通过递归比较右子树的节点,直到插入到合适的位置
 
   看下面的例子:

2.查找操作
  查找操作比较简单,如果该值等于根节点的值,则直接返回。如果该值大于根节点的值,则到右子树中进行递归查找,然后返回查询结果。如果该值小于根节点的值,则到左子树中进行递归查找,然后返回查询结果。
 
3.删除操作
 1.如果该节点是叶子节点,则直接将其删除
 2.如果该节点有一个子节点,则将该节点的父节点指向该节点的子节点,然后将该节点删除。
 3.如果该节点有两个子节点,一般的删除策略是用该节点的右子树中的最小节点值代替该节点的值,然后再递归的删除该最小节点,因为这是最小的节点,不可能再有左子树,所以删除的时候会简单一些(因为没有左子树所以该节点最多只有一个右子树,删除策略同2)。
 
 看下面的例子:


 概念介绍完了,现在用程序来实现一个简单的二叉查找树
 
package com.algorithm;

/**
 * 二叉查找树
 * @author 马永华
 *
 */
public class Bst {
	
	//定义二叉树的数据结构
	static class BinaryNode<T> {
		
		 private  T element;
		 private BinaryNode<T> left;
		 private BinaryNode<T> right;
		 
		 //创建一个单节点
		 public BinaryNode(T element){
			 this(element,null,null);
		 }
		 
		 //创建子节点
		 public BinaryNode(T element,BinaryNode<T> left,BinaryNode<T> right){
			 this.element = element;
			 this.left = left;
			 this.right = right;
		 }

	} 
	
	//插入
	public BinaryNode<Integer> insert(Integer i,BinaryNode<Integer> node){
		
		if(node == null){
			return new BinaryNode<Integer>(i);
		}
		
		//如果i 小于当前节点的值,则查找器左子树
		if(i < node.element) {
			node.left = insert(i,node.left);
		}
		
		//如果i 大于当前节点的值,则查找其右子树
		if(i > node.element) {
			node.right = insert(i,node.right);
		}
		
		return node;
 	}
	
	//查找
	public BinaryNode<Integer> find(int i,BinaryNode<Integer> node){
		//如果树为空,则直接返回null
		if(node == null) 
			return null;
		
		if(node.element == i)
			return node;
		
		if(i < node.element)
			return find(i,node.left);
		
		if(i > node.element) 
			return find(i,node.right);
		
		System.out.println("这里会执行吗");
		return null;
	}
	
	//查询树的最大值
	public BinaryNode<Integer> findMax(BinaryNode<Integer> node){
		//如果树为空,则直接返回null
		if(node == null) 
			return null;
		
		if(node.right == null)
			return node;
		else 
			return findMax(node.right);
	}
	
	//查询树的最小值
	public BinaryNode<Integer> findMin(BinaryNode<Integer> node){
		//如果树为空,则直接返回null
		if(node == null) 
			return null;
		
		if(node.left == null)
			return node;
		else 
			return findMin(node.left);
	}
	
	//获得当前节点的父节点
	public BinaryNode<Integer> findParent(int i,BinaryNode<Integer> node){
		
		if(node == null)
			 return null;
		
		//如果i的值小于
		if(i<node.element){
			if(node.left != null &&i == node.left.element)
			return node;
			else 
			return findParent(i,node.left);
		}
		
		//如果该值
		if(i>node.element){
			if(node.right != null && i == node.right.element)
				return node;
			else
				return findParent(i,node.right);
		}
		
		return null;
	}
	
	//删除节点
	public BinaryNode<Integer> delete(int i,BinaryNode<Integer> node){
		
		if(node == null)
			return null;
		
		if(i<node.element){
			//如果要删除的节点小于当前节点
			node.left = delete(i,node.left);
		}else if(i>node.element){
			//如果要删除的节点大于当前节点
			node.right = delete(i,node.right);
		}else {
			//要删除的节点等于当前节点
			//如果该节点有两个子节点
			if(node.left !=null && node.right !=null){
				//找到该节点右子树中最小的节点,将它的值赋给当前节点
				node.element = findMin(node.right).element;
				//然后递归去删除这个最小的节点
				node.right = delete(node.element,node.right);
			}else {
				//如果该节点有一个子节点或者没有子节点
				return node = node.left != null ? node.left : node.right;
			}
			
		}
			return node;
	}
	
	//对二叉查找树进行中序输出,输出的是一个从小到大的有序数列
	public void sort(BinaryNode<Integer> node){
		
		//先输出左子树
		if(node.left != null){
			sort(node.left);
		}
		
		//再输出中间
		System.out.print(node.element+"->");
		
		//最后输出右子树
		if(node.right != null){
			sort(node.right);
		}
		
		
	}
	
	public static void main(String args[]){
		Bst bst = new Bst();
		
		//插入 6 2 8 1 5 3 4
		BinaryNode<Integer> root = bst.insert(6, null);
		bst.insert(2, root);
		bst.insert(8, root);
		bst.insert(1, root);
		bst.insert(5, root);
		bst.insert(3, root);
		bst.insert(4, root);
		
		//查询
		BinaryNode<Integer> node2 =  bst.find(2, root);
		BinaryNode<Integer> node0 =  bst.find(0, root);
		BinaryNode<Integer> nodeMax =  bst.findMax(root);
		BinaryNode<Integer> nodeMin =  bst.findMin(root);
		
		//排序
		bst.sort(root);
		
		//删除
//		BinaryNode<Integer> delete4 = bst.delete(4,root);
//		BinaryNode<Integer> delete3 = bst.delete(3,root);
//		BinaryNode<Integer> delete2 = bst.delete(2,root);
	}
}


     
  • 大小: 14.4 KB
  • 大小: 13.5 KB
  • 大小: 34.3 KB
  • 大小: 47.6 KB
10
0
分享到:
评论
1 楼 hailongshih 2013-05-14  
Good,好文

相关推荐

    中科大 算法导论 课件(全套1)

    - 红黑树:一种自平衡二叉查找树,用于实现高效的查找、插入和删除操作。 - B树:一种多路平衡查找树,常用于文件系统和数据库索引中,以优化磁盘访问时间。 5. **算法研究问题**: - NP完全问题:属于复杂性...

    Dr. Mallier Computer Science JAVA

    - **树与二叉查找树**:讨论树结构的基本概念以及二叉查找树的应用。 - **哈希表**:介绍哈希表的工作原理及其在实际应用中的重要性。 - **图论**:探索图的基本概念和图算法,如最短路径问题等。 #### 五、软件...

    Algorithm教程

    - **分摊时间在伸展树中的应用**:伸展树是一种自调整二叉搜索树,其性能取决于分摊时间分析。 ##### 3. 伸展树 - **伸展树操作的应用**:这部分解释了伸展树的操作及其应用场景。 - **伸展树操作的时间分析**:...

    浙江大学《数据结构》上课笔记 + 数据结构实现 + 课后题题解

    中国大学MOOC上浙大的《数据结构》广受好评,原因有二,一是基础,简单易懂,老师讲得也清楚,另一大优点就是配套的每周相应知识点的编程题了,有难有易,容易题帮助巩固知识点,难题开阔视野。 笔记加入了一些自己...

    13、(CSP-S) 提高级 C++ 语言试题 海亮内部模拟卷-试题.pdf

    - 平衡树是一种自平衡的二叉搜索树,能够保持树的高度尽可能低,从而提高查找效率。 - 与普通二叉搜索树相比,平衡树能确保在最坏情况下也能维持较低的时间复杂度。 - **常见的平衡树类型**: - **Splay树**:一...

    东大电气数据库第一次作业

    - **数据结构选择**:考虑到集合中元素的任意性和多样性,应选用支持高效查找和插入操作的数据结构,如哈希表或平衡二叉搜索树(例如AVL树)。这些结构能有效减少元素重复检查的时间复杂度,确保集合运算的高效性。 ...

    数据结构, 浙大的PPT哦,很值得一看, 不过是基础篇

    这些结构用于实现高效的查找和排序,比如二叉搜索树用于快速查找,堆用于优先级队列。 3. **图结构**:图用于表示实体之间的复杂关系,例如在网络路由、社交网络分析等领域有广泛应用。 4. **排序和查找算法**:...

    leetcode中文版-LeetCode:算法练习:LeetCode问题、LeetCode每周竞赛等

    二叉搜索树 数学: 概率:洗牌算法、蓄水池抽样、蒙特卡洛 数论:素数,最小公倍数,最大公约数 位运算:异或,与的巧妙用法 特殊的数:有效数字(状态机),第n个丑数,平方数(DP解法),回文数 数字的转化:溢出...

    leetcode提交要达到-ad325:AD325-数据结构和算法

    leetcode提交要达到班级详情 地点:远程 时间:周二或周四 6:00 - 8:40 pm 日期:01/05/2021 - 03/23/2021 ...小结本课程涵盖计算机科学核心...二叉搜索树 哈希表 图和路径查找 字符串算法和正则表达式 压缩算法 课程材料

    数据结构10-11(1)数据结构理论课教学计划(68学时).pdf

    9. **查找**:9.1基本概念,9.2静态查找表,9.3二叉排序树,9.4平衡二叉树,9.5 B树和B+树,9.6哈希表查找,涉及各种高效的查找技术。 课程中穿插了习题课和课堂讨论,以检验学生对知识的理解和应用能力,并通过...

    c语言编写职员轮班休息程序

    - **排序算法**:可以先对职员的休息日进行排序,便于查找冲突。可以使用冒泡排序、插入排序、快速排序等。 - **优先级队列**:如果某个职员的休息日更早,可以考虑优先满足他的需求,可以使用二叉堆实现。 4. **...

    leetcode融资-100-hard-level-algorithms-2018-summer-campaign:2018年夏季开始的100

    leetcode 融资创建广告系列的想法是 。 2018-8月 促使自己努力思考并根据时间复杂度瞄准最佳解决方案总是好的。 ...我需要练习写一个基于联合查找算法的解决方案,并在45分钟内完成。 我需要每周一

    April-2021-LeetCode-Challenge

    4. **树结构**:二叉树是常见的一种数据结构,包括二叉搜索树、完全二叉树、满二叉树、平衡树(AVL树、红黑树)等。树相关的题目可能涉及遍历(前序、中序、后序)、查找、插入和删除节点等操作。 5. **图算法**:...

    MyCalendar:一个用于组织日程安排的简单应用程序。 一个简单的应用程序,用于组织您的日程安排。

    例如,日程数据可能被组织成一个二叉搜索树或红黑树,这样在进行查找、插入和删除操作时,时间复杂度可以保持在O(log n)。此外,为了实现日程冲突检测,MyCalendar可能使用了时间区间交叉检查算法,避免在同一时间段...

Global site tag (gtag.js) - Google Analytics