笛卡尔树

笛卡尔树是单调栈的延伸应用
定义:

  • 树中元素的值符合堆的性质
  • 树中元素的索引符合二叉搜索树的性质

中序遍历得到的就是原序列。

建树:
由于当前任何根的左子树的索引值都更小,所以不能插入到左子树上,因此笛卡尔树插入一个元素 x x x时是从最右链开始,每次从最右链底部开始向上搜索到第一个值小于等于元素 x x x的值的元素 y y y,将 y y y的右子树作为 x x x的左子树,将 x x x作为 y y y的右子结点。

  • y y y的右子树作为 x x x的左子树是因为 y y y的右子树在 x x x插入前先出现,故为了保证中序遍历时依然优先遍历 y y y的右子树,所以将其作为 x x x的左子树。
  • x x x作为 y y y的右子结点依然是因为 y y y优先于 x x x出现,故为了保证中序遍历时依然优先遍历 y y y,所以将 x x x作为 y y y的右子树。
  • 建树时在树中存索引即可。
int ls[N], rs[N], stk[N];
int top;
int q[N], n;

void build() {
	top = 0;
	for(int i = 1; <= n; ++i) {
		int temp = top;
		while(temp > 0 && q[stk[temp]] > q[i]) --temp;
		if(temp) rs[stk[temp]] = i;
		if(temp < top)  ls[i] = stk[temp + 1]; //非叶子
		stk[++temp] = i;
		top = temp;
	}
}

最后栈中存储的是从根结点开始的一条右链,直到结点无右子树为止。

你可能感兴趣的:(单调栈,笛卡尔树)