基本信息
文件名称:数据结构 课件 第12--14章 高级查找;外排序; 索引.pptx
文件大小:10.48 MB
总页数:10 页
更新时间:2025-05-19
总字数:约5.16万字
文档摘要

数据结构

计算机领域本科教育教学改革试点

工作计划(“101计划”)研究成果

俞勇、张铭、陈越、韩文弢

上海交通大学、北京大学、浙江大学、清华大学

101

12.1线段树

第12章高级查找

戴波

电子科技大学

12.1.1线段树的定义

12.1.2线段树的存储

12.1.3线段树的操作

12.1.4小结

12.1.5作业

12.1.1线段树的定义

12.1.1线段树的定义

数据结构

线段树是满足下面条件的二叉查找树seg_tree:根结点p=1记为seg_tree[p]=v,表示线段区间[l,r]的值是v——例如为查找区间最小值而设计的线段树中,这个值就是区间内所有元素的最小值,如果是为求区间和设计的线段树,这个值就是区间内所有元素的和。区间的长度n=r-l+1。

如果n1:则seg_tree[2p]是区间[l,r]的左儿子的值,表示的范围是[l,(l+r)/2];seg_tree[2p+1]是区间[l,r]的右儿子的值,表示的范围是[(l+r)/2+1,r]。

如果n=1:seg_tree[p]是叶结点。

12.1.1线段树的定义

12.1.1线段树的定义

数据结构

求[1,14]区间最小值的线段树

说明2:线段树采用二分法进行构造,因此是平衡二叉树,线段树的结点总数=叶结点个数n+内部结点个数n-1=2n-1

说明1:根结点seg_tree[1]=3,即[1,14]范围的最小值是3

12.1.2线段树的存储

12.1.2线段树的存储

数据结构

线段树是二叉查找树,可以采用二叉链表存储,也可以扩充为完全二叉树按照层序编号,用数组存储线段树的数据。

根据完全二叉树用数组存储的性质:第i个结点如果有双亲,双亲在[i/2](i1)位置,如果有左右孩子,则左孩子在2*i(i1)位置,右孩子在2*i+1(i1|1)。

如下图[1,14]范围求最小值的线段树,圆圈外的数字就是存储在数组的索引。

12.1.3线段树的操作

12.1.3线段树的操作

数据结构

12.1.3线段树的点操作

12.1.3线段树的操作

数据结构

例:修改下面线段树索引7的值为1

如果修改[a,b]范围的索引为k的数据为x,则只需要从根,按照二分搜索方法,判断k与m=(a+b)/2的大小关系,确定线段树的搜索路径,直到到达m=k的叶结点,修改T[k]=x,并在回溯的时候修改沿路的对应的区间值,具体操作如线段树的初始化的思维导图的步骤2所示。

12.1.3线段树的点操作

12.1.3线段树的操作

数据结构

解析:

12.1.3线段树的区间操作

12.1.3线段树的操作

数据结构

如果在[a,b]线段树中求[L,R]范围内的区间结果(比如求最小值/最大值/求和值等),可以采用线段树的区间操作,步骤如下:

首先判断[L,R]是否在线段树范围[a,b]中,如果不在,则区间操作结束,操作结果为0。

否则就在范围内,然后判断范围是否刚好是[a,b],如果是,则根结点的值就是[L,R]的值;

否则计算m=(a+b)/2,如果Rm,则操作范围缩小在左分支继续;或者Lm,则操作范围缩小在右分支继续;否则左右分支都要进一步进行区间的递归操作。

也就是说,如果区间操作在线段树的某个区间,则先从所在分支向下递归定位所在分支,会覆盖左右分支的部分结点和中间部分结点。其中两侧的结点一直向下递归到子树的L=a,R=b的时候才停止向下,然后回溯。所以左右两侧的最多向下递归到叶结点,中间的在L=a,R=b就停止了。所以最大的递归次数是不超过两侧的树高。

12.1.3线段树的区间操作

12.1.3线段树的操作

数据结构

解析:(1)p=1,m=(1+14)/2=7;3m9,左右子树都进一步求解

(2)p=1的左子树:p=2,m=(1+7)/2=4;3m7,左右子树进一步求解

p=1的右子树:p=3,m=(8+14)/2=11;8m14,左右子树进一步求解

(3)p=2左子树p=4:m=(1+4)/2=2,2m,只到右子树p=9,返回6

p=2的右子树:[5,7]在[3,9]范围之内,返回4

V[3,7]=min(V[3,4],V[5,7])=min(6,5)=5;

(4)p=3的左子树p=6:m=(8+11)/2=9,只到左子树,返回4

(5)V[3,9]=min(V[3,7],V[8,9])=min(5,4)=4

例:快速求出[L,R]区间的最小值V[L,R],其中1=L=R=14

12.1.3线段树的区间操作

12.1.3线段树的操作

数据结构

例题:已知10000个正整数,用A数组存储这10000个正整数。其中A[i]表示存储的第i个数(1