线段树的简单实现和查询(修改)
来源:互联网 发布:淘宝上苏泊尔是正品吗 编辑:程序博客网 时间:2024/06/06 03:34
做题时经常会遇到自区间查询的问题,这里我们引用经典的题目:
在一个长度为n的数组中(无序的),查找某个子区间中的最小值。
如果用普通方式写,需要有O(n^2)的处理时间,O(1)的查找效率,但是如果用线段树则是O(n)构造时间,logn的查询时间。
在这里我定义一个线段树T:
#define N 10#define INFINITE 99999999 int arr[N] = {2,5,6,12,4,1,3,23,43,0};int T[N];//线段树 //i为起始角标,j为末尾角标 void createTree(int root,int i,int j){ if(i==j){ T[root] = arr[i]; }else{ int mid = (i + j) / 2; createTree(root * 2 + 1,i,mid); createTree(root * 2 + 2,mid+1,j); T[root] = min(T[root*2+1],T[root*2+2]); }}//i,j为当前区间,ii,jj为需要查询的区间 int query(int root,int i,int j,int ii,int jj){ if(jj < i || ii > j)return INFINITE; if(i >= ii && j <= jj)return T[root];//如果当前区间为需要查询的区间内,则返回该数 int mid = (i + j) / 2; return min(query(root*2+1,i,mid,ii,jj),query(root*2+2,mid+1,j,ii,jj));//折半后分2边查找最小值 }
节点的更新:
void updateNode(int root,int i,int j,int index,int value){ if(i==j){ if(index == i)T[root] = value; }else{ int mid = (i + j) / 2; if(index <= mid) updateNode(root*2+1,i,mid,index,value); else updateNode(root*2+2,mid+1,j,index,value); T[root] = min(T[root*2+1],T[root*2+2]);//根据回溯,可以从根据已修改的节点来判断出最大最小值。 }}
完整代码:
#include<iostream>#include<algorithm>using namespace std;#define N 10#define INFINITE 99999999 int arr[N] = {2,5,6,12,4,1,3,23,43,0};int T[N];//线段树 //i为起始角标,j为末尾角标 void createTree(int root,int i,int j){ if(i==j){ T[root] = arr[i]; }else{ int mid = (i + j) / 2; createTree(root * 2 + 1,i,mid); createTree(root * 2 + 2,mid+1,j); T[root] = min(T[root*2+1],T[root*2+2]); }}void updateNode(int root,int i,int j,int index,int value){ if(i==j){ if(index == i)T[root] = value; }else{ int mid = (i + j) / 2; if(index <= mid) updateNode(root*2+1,i,mid,index,value); else updateNode(root*2+2,mid+1,j,index,value); T[root] = min(T[root*2+1],T[root*2+2]);//根据回溯,可以从根据已修改的节点来判断出最大最小值。 }}//i,j为当前区间,ii,jj为需要查询的区间 int query(int root,int i,int j,int ii,int jj){ if(jj < i || ii > j)return INFINITE; if(i >= ii && j <= jj)return T[root];//如果当前区间为需要查询的区间内,则返回该数 int mid = (i + j) / 2; return min(query(root*2+1,i,mid,ii,jj),query(root*2+2,mid+1,j,ii,jj));//折半后分2边查找最小值 }void print(){ for(int i = 0;i<N;i++) printf("%d ",arr[i]); printf("\n");}int main(){ createTree(0,0,N-1); int start = 0; int end = 9; print(); printf("[%d - %d]的最小子值为%d",start+1,end+1,query(0,0,N-1,start,end));}
阅读全文
0 0
- 线段树的简单实现和查询(修改)
- 线段树的构造、查询和修改
- 敌兵布阵 简单的线段树单点修改 + 单点查询
- [模板练习]线段树的单点修改和区间查询
- 基础线段树的 修改与查询
- [线段树][区间修改&&查询]
- tyvj P1039 线段树点修改和区间查询
- 线段树简单实现
- hdu1166 敌兵布-线段树的简单应用-查询更改
- 线段树实现动态查询和删节点
- HDU 5245 Joyful(线段树、查询区间和及修改区间每个数为数的平方)
- HDU 4027 Can you answer these queries?(线段树、查询区间和及修改区间数为数的平方根)
- 线段树的修改
- 线段树的修改
- 线段树的修改
- 线段树的查询
- 线段树的查询
- 线段树点修改 区间查询
- linux内存分配与回收
- 总线式布线
- 图论_模板
- NumPy基本使用
- 栈
- 线段树的简单实现和查询(修改)
- 电影《亲爱的》观后感
- #443 Div.2 B. Table Tennis 排队游戏 && 细节
- 字符串匹配的KMP算法
- selenium安装、配置及使用+java
- JS中文字前面加图标
- 2.redis常见概念
- 离散变量的典型分布
- 脑科学家鲁白:在这五个方面电脑是胜不过人脑的 | 演讲