二叉搜索树

来源:互联网 发布:mac的常用快捷键 编辑:程序博客网 时间:2024/05/17 05:03

--------------------siwuxie095

  

  

  

  

  

  

  

  

二叉搜索树

  

  

这里介绍二叉搜索树(Binary Search Tree)

  

二叉搜索树,顾名思义,本质上也是一棵二叉树

  

  

  

二叉树在计算机中是一种非常常用的数据结构,选择什么类型的二叉树

很多时候要根据需要解决的问题而定

  

使用数据结构的核心是要解决问题,而并非是为了使用数据结构而使用

数据结构

  

使用二叉树并不是因为二叉树很酷,很炫,听起来很专业,而是因为二

叉树能够高效的解决一类问题

  

  

  

二叉搜索树解决的一类问题就是在计算机中非常常见的查找问题

  

「查找问题是计算机中非常重要的基础问题」

  

可能很多人会觉得这个问题非常简单,就是在一组数据中找到某

个数据,但是仔细想一想就会发现,查找问题虽然描述出来很简

单,但是它的应用却非常广泛

  

从去银行办理业务时,银行根据证件号码从系统中调出相应的信

息,到在Google 中搜索内容时,Google 根据关键字来查找相

关的信息

  

查找问题,是一个听起来非常朴素,实际上却非常困难,被研究

的非常广泛的一类问题

  

「查找问题,即 Search Problem」

  

  

  

  

  

  

  

二叉搜索树的优势

  

  

事实上,二叉搜索树,通常都用于实现查找表

  

有的地方,也称查找表字典,如下:

  

key1

value1

key2

value2

key3

value3

key4

value4

key5

value5

  

对于这些数据而言,都是一个一个键值对,即key-value

对应的数据对,给你一个key,相应的就有一个 value

  

这样大量的数据对,集合在一起就形成了一张表,在这张表

中通过键(key)就能直接查到对应的值(value)

  

  

  

最典型的一个应用就是字典。对于一个字典来说,键(key)

就是一个个单词,而值(value)就是单词的释义

  

这也是查找表有时候也被称为字典这样一种数据结构的原因

  

  

  

如果这些key 都是整数,而且范围比较小,那么使用数组就可以轻易

地用索引直接来索引到相应的value

  

但在实际的业务逻辑中,很多时候不能用整数来表达这样的键(key),

或者是因为这些键(key)相对比较稀疏,使用数组在空间上并不经济,

或者是因为这些键(key)压根就不能用整数来表示

  

例如:字典的键(key)其实是一个字符串

  

这种情况下,就需要实现一个查找表,而实现查找表的最基础的一个

方式是实现二叉搜索树

  

当然,也完全可以用普通数组顺序数组来实现这个一个查找表

  

  

查找元素

插入元素

删除元素

普通数组

O(n)

O(n)

O(n)

顺序数组

O(lgn)

O(n)

O(n)

二分搜索树

O(lgn)

O(lgn)

O(lgn)

  

  

可以简单分析一下使用普通数组顺序数组的时间效率:

  

1)使用普通数组

  

查找一个元素,就需要使用 O(n) 的时间从头到尾遍历一遍,看要找的

那个元素在数组的什么位置

  

插入一个元素,也需要使用O(n) 的时间从头到尾遍历一遍,因为对于

查找表来说,需要先看一看当前查找表中是否已经含有要插入的元素。

如果没有,再插入;如果有的话,就应该是对key 相应的value 进行

一个更新操作

  

删除一个元素,也需要使用 O(n) 的时间从头到尾遍历一遍,来删除相

应的元素

  

  

2)使用顺序数组

  

要一直保证这个数组是有序的。这样一来,查找一个元素就可以使用

二分查找法,用O(lgn) 的时间进行查找,但对于插入一个元素和删除

一个元素来说,依然要使用O(n) 的时间

  

  

  

相较而言,二叉搜索树就高效很多,它能够保证查找、插入、删除这

三个操作的时间复杂度近乎都是O(lgn) 级别的

  

  

  

所以,二叉搜索树的优势:

  

1)高效

  

不仅可以高效查找数据,还可以高效地插入数据、删除数据- 动态维护数据

  

也就是说,如果能一下就把所有的数据拿到手,那可能先对数据进行排序再

使用二分查找法,就足够了

  

但在很多时候,查找、插入、删除这三个操作,在业务的过程中都是要涉及

的,因此,二叉搜索树提供了一个可以非常高效地动态维护数据的方式

  

  

2)可以方便地回答很多数据之间的关系问题,如下:

  

minmaxfloorceilrankselect

  

可以轻易地找到所有数据中的最小值min、最大值 max,某个数据的floor

相应的值、ceil 相应的值,还有给定一个数据,求它的排名rank,以及找

到所有数据中某排名(如:第 100 名)的数据select

  

  

  

  

  

  

  

二叉搜索树的定义

  

  

如下图所示,是一棵二叉搜索树:

  

  

  

二叉搜索树,是指一棵空树或者具有下列性质的二叉树:

  

1)若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值

2)若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值

3)任意节点的左、右子树也分别为二叉搜索树

4)没有键值相等的节点

  

  

  

  

1)每个节点的键值都大于左孩子

2)每个节点的键值都小于右孩子

  

  

  

不难看出,二叉搜索树的定义中天然就包含了递归结构

  

正因为如此,在对二叉搜索树编程时,很多时候都可以使用递归函数的方式,

方便快速地实现很多功能

  

  

  

注意:对于堆来说,堆的那棵二叉树一定是一棵完全二叉树,但对于二叉搜索

树来说,是没有这个限制的,如下:

  

  

  

换句话说,上图中的这棵树,也是二叉搜索树,即二叉搜索树,不一定是

完全二叉树

  

在实现堆的时候,是利用了堆一定是一棵完全叉树的特点,所以能用数组

来表示堆,但二分搜索树不一定是完全二叉树,所以用数组表示并不方便

  

因此,通常是设立Node 节点,来表示 key-value 这样的数据对,而节点

之间的联系,则使用指针的方式来表示

  

  

  

  

  

  

  

  

  

【made by siwuxie095】