数据结构——笛卡尔树详解

数据结构------笛卡尔树

1,笛卡尔树的介绍

前面我们讲过《堆》《二叉搜索树》,能不能把这两种数据结构的特性结合起来构造一棵新的树呢?当然是可以的,这个就是我们这里要讲的笛卡尔树(Cartesian tree)。

笛卡尔树的每个节点有两个值 (x,y) ,其中一个满足二叉搜索树的特性,一个满足堆的特性,所以笛卡尔树是一棵具有二叉搜索树和堆的两种特性的二叉树

笛卡尔树中节点的两个值分别是数组中元素的值,和该元素在数组中的下标,其中元素的值满足堆的特性,元素的下标满足二叉搜索树的特性。

下面使用数组 [5, 6, 3, 8, 9, 1, 4, 7, 2] 构造一棵笛卡尔树。

2,笛卡尔树的构建

因为元素的下标满足二叉搜索树的特性,而数组中元素的下标又是递增的,所以新插入的节点要么是根节点,要么是根节点右子树上的某个节点,不可能是根节点左子树上的某个节点

所以节点插入的时候不需要考虑左子树,又由于元素的值满足堆的特性(这里我们选择最小堆),如果新插入的节点比根节点小,那么新节点就变成根节点的父节点,根节点就变成新节点的左子节点,如下图所示。

如果新节点的值比根节点大,那么新节点一定是根节点右子树上的某个节点,根节点的右子树节点可能很多,究竟插入到哪个位置呢?

实际上笛卡尔树的任何一棵子树也都是笛卡尔树,那么右子树当然也满足插入规则,如果新节点比根节点的右子节点小,那么根节点的右子节点是新节点的左子节点,新节点变成根节点的右子节点,如果新节点比根节点的右子节点大,继续和根节点右子节点的右子节点比较......

也就是说插入的时候新节点会和根节点一直往右的这条路径上的节点比较,为了方便比较我们可以使用一个栈来记录从根节点一直往右走的所有节点,很明显这个栈从栈顶到栈底是单调递减的,每次比较的时候不在从根节点开始,而是从栈顶元素开始比较,这个栈顶元素就是根节点一直往右走,最右边的节点。

这里我们选用最小堆,来看下笛卡尔树的构建步骤:

1,用数组中的第一个元素创建根节点,然后把根节点添加到栈中。

2,遍历数组的剩余元素,然后创建新节点和栈顶元素比较,如果栈不为空并且栈顶元素比新节点大,栈顶元素出栈。一直比较,直到栈为空或者栈顶元素小于新节点为止。

3,如果栈为空,让新节点变成根节点的父节点,根节点变成新节点的左子节点。

4,如果栈不为空,让最后一个出栈的节点变成新节点的左子节点,新节点变成栈顶元素的右子节点。

5,新节点入栈,继续重复步骤2,3,4,5,直到数组遍历完为止。

我们以数组 [5,6,3,8,9,1,4,7,2] 为例,来看下笛卡尔树的构建过程:


3,笛卡尔树的代码实现

相关推荐
野生的编程萌新3 小时前
从冒泡到快速排序:探索经典排序算法的奥秘(二)
c语言·开发语言·数据结构·c++·算法·排序算法
花开富贵ii5 小时前
代码随想录算法训练营四十三天|图论part01
java·数据结构·算法·深度优先·图论
code小毛孩6 小时前
leetcode hot100数组:缺失的第一个正数
数据结构·算法·leetcode
艾伦~耶格尔13 小时前
【数据结构进阶】
java·开发语言·数据结构·学习·面试
闪电麦坤9515 小时前
数据结构:N个节点的二叉树有多少种(Number of Binary Trees Using N Nodes)
数据结构·二叉树·
快去睡觉~16 小时前
力扣400:第N位数字
数据结构·算法·leetcode
汤永红17 小时前
week1-[循环嵌套]画正方形
数据结构·c++·算法
pusue_the_sun18 小时前
数据结构——顺序表&&单链表oj详解
c语言·数据结构·算法·链表·顺序表
yi.Ist18 小时前
图论——Djikstra最短路
数据结构·学习·算法·图论·好难
数据爬坡ing19 小时前
过程设计工具深度解析-软件工程之详细设计(补充篇)
大数据·数据结构·算法·apache·软件工程·软件构建·设计语言