博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
笛卡尔树
阅读量:4502 次
发布时间:2019-06-08

本文共 1819 字,大约阅读时间需要 6 分钟。

笛卡尔树又称笛卡儿树,在数据结构中属于二叉树的一种。

笛卡尔树结构由Vuillmin在解决范围搜索的几何数据结构问题时提出的,从数列中构造一棵笛卡尔树可以线性时间完成,需要采用基于栈的算法来找到在该数列中的所有最近小数。由此可知,笛卡尔树是一种特定的二叉树数据结构,可由数列构造,在范围最值查询、范围top k查询(range top k queries)等问题上有广泛应用。它具有堆的有序性,中序遍历可以输出原数列。

笛卡尔树是一棵二叉树,树的每个节点有两个值,一个为key,一个为value。光看key的话,笛卡尔树是一棵二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大;光看value的话,笛卡尔树有点类似堆,根节点的value是最小(或者最大)的,每个节点的value都比它的子树要大。

构造笛卡尔树的过程:

使用数据结构栈,栈中保存的始终是右链,即根结点、根结点的右儿子、根结点的右儿子的右儿子……组成的链

并且栈中从栈顶到栈底key依次减小

如果按照从后到前的顺序判断一个元素是否大于A[i],则每次插入的时间复杂度为O(k+1)
k为本次插入中移除的右链元素个数。因为每个元素最多进出右链各一次,所以整个过程的时间复杂度为O(N)。

从前往后遍历A[i],

1.对于每一个A[i],从栈中找出(从栈顶往栈底遍历,或者从数组后往前遍历)第一个小于等于A[i]的元素
2.如果找到,i.parent为sta[k],同时sta[k].r=i,即i为sta[k]的右子树,
3.如果栈中存在比A[i]大的元素 这些元素肯定是出栈了,这个问题最后的代码统一表示。
同时,sta[k+1].parent=i; i.l=sta[k+1] 即sta[K+1]为i的左子树
4.最后i入栈,比i大的A[i]都自动出栈了。

例子如下。
0 1 2 3 4 5 6 7 8  9      .....key
3 2 4 5 6 8 1 9 10 7      .....A,value

stack

0 1 2 3 4 5 6 7 8  ...num
0
1 2 3 4 5
6 7 8
6 9
最后sta[0].parent=-1;  为根节点 即 6 为根节点。

这里给出的是索引从0开始的[0,n-1]

如果题目给出的是[1,n],可以减一回到[0,n-1]上

代码:

View Code
1 #include 
2 #include
3 using namespace std; 4 const int maxnum=10; 5 6 int a[maxnum]; 7 struct node 8 { 9 int key;10 int parent;11 int l;12 int r;13 }tree[maxnum];14 15 16 void Init()17 {18 int i;19 for(i=0;i
=0 && a[stack[k]]>a[i]) //栈中比当前元素大的都出栈32 k--;33 34 if(k!=-1) //find it,栈中元素没有完全出栈,当前元素为栈顶元素的右孩子35 {36 tree[i].parent=stack[k];37 tree[stack[k]].r=i;38 }39 if(k
q;65 q.push(node);66 while(!q.empty())67 {68 int k=q.front();69 q.pop();70 cout<
<
>a[i];85 tree[i].key=a[i];86 }87 88 int root=Build_Tree();89 90 //inorder(root);91 //levelorder(root);92 return 0;93 }94 95 /*96 3 2 4 5 6 8 1 9 10 797 */

 

转载于:https://www.cnblogs.com/pushing-my-way/archive/2012/08/24/2653709.html

你可能感兴趣的文章
sqlalchemy学习(一)
查看>>
silverlight Image Source URI : 一个反斜杠引发的血案
查看>>
Windows Phone开发(35):使用Express Blend绘图 转:http://blog.csdn.net/tcjiaan/article/details/7493010...
查看>>
Windows Phone开发(33):路径之其它Geometry 转:http://blog.csdn.net/tcjiaan/article/details/7483835...
查看>>
Android入门(9)AudioRecord和AudioTrack类的使用【转】http://blog.sina.com.cn/s/blog_6309e1ed0100j1rw.html...
查看>>
mybatis整合Spring编码
查看>>
第七章 路由 68 路由-前端路由和后端路由的概念
查看>>
dpkg包管理
查看>>
前端JS利用canvas的drawImage()对图片进行压缩
查看>>
一键切换皮肤的解决思想及iframe嵌套时寻找下级iframe的方法
查看>>
van-dialog 组件调用 报错
查看>>
VC++中的__super::
查看>>
DS1-14
查看>>
c# Mongodb两个字段不相等 MongoDB原生查询
查看>>
排序算法-冒泡排序
查看>>
finally 的作用是什么?
查看>>
嵌入式Linux的调试技术
查看>>
CSS3
查看>>
用友U9 基础使用文件所在目录
查看>>
iOS CALayer 学习(1)
查看>>