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

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

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,笛卡尔树的代码实现

相关推荐
J_admin29 分钟前
数据结构 之 二叉树的遍历------先根遍历(五)
数据结构
黑不拉几的小白兔6 小时前
PTA L1系列题解(C语言)(L1_097 -- L1_104)
数据结构·算法·1024程序员节
秋说6 小时前
【数据结构 | PTA】懂蛇语
数据结构·c++
ChaoZiLL7 小时前
关于我的数据结构与算法——初阶第二篇(排序)
数据结构·算法
single5948 小时前
【综合算法学习】(第十篇)
java·数据结构·c++·vscode·学习·算法·leetcode
free_girl_fang9 小时前
夯实根基之MySql从入门到精通(一)
java·数据结构·数据库·mysql
Lonelinessser9 小时前
数据结构——基础知识补充
数据结构
凡尘技术9 小时前
算法实现 - 快速排序(Quick Sort) - 理解版
java·数据结构·算法
wh233z9 小时前
Codeforces Round 981 (Div. 3) (A~F)
c语言·数据结构·c++·算法
字节卷动9 小时前
【牛客算法】某司面试算法题:循环右移二叉树
数据结构·算法·leetcode·面试·牛客