关于划分树的简单介绍


有那么一类区间查询问题:给定一个无序的数组,查询一个给定区间中的第k大数。

简单的想法是把区间中的数排序,下标为k的数就是我们要找的,但是如果查询次数很多,即使是归并排序这种高效的排序算法也会超时,这时,我们要使用一种新的数据结构----划分树。


定义:它的每一个节点保存区间[lft,rht]所有元素,元素顺序与原数组(输入)相同,但是,两个子树的元素为该节点所有元素排序后(rht-lft+1)/2个进入左子树,其余的到右子树,同时维护一个num域,num[i]表示(lft,i)这个区间中有多少个点进入了左子树。

可以看到,建树的过程和快速排序的过程很相似,只不过在排序的过程中顺便记录下num这个数组,从而可以实现快速查询。


下面找个例子看一下这个算法的模拟过程:

在 [ 2 4 3 5 8 1 7 6 ] 中找区间[2,7]的第2小
①           [ 2 4 3 5 8 1 7 6 ]            // 原数组  [2,7]找第2小
②     [ 2 4 3 1 ]         [ 5 8 7 6 ]      // 分成左右两组  知道[2,7]中有3个到左子树  故在答案左
③  [ 2 1 ]   [ 4 3 ]    [ 5 6 ]  [ 8 7 ]   // 同理  只有1个到左子树  故答案在右子树
④  [1] [2]   [3] [4]    [5] [6]  [7] [8]   // 一直迭代直到找到答案


关于模板:

这种与某种数据结构有关的算法,最好的模板就是封装的结构体或者类,这样的模板在稳定性和性能上都会有所保证,使用起来也会更加方便。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值