pat1043
[题目]
[link]大致意思是判断一个插入序列是否是合法的BST/镜像BST先根序列,如果是的话,求它的后根
[基本思路]
- 首先利用递归判断是否是合法的BST或者镜像BST的先根遍历
原理: root是第一个元素, 比root小的 // 比root大的 聚集在一起
方法2:也可以把它作为插入序列,跟据他构建一个BST树,再求这个新建的BST的先根序列,如果一致,则之前那个插入序列就是先根序列.
- 判断出如果是合法的BST前缀,按照此作为插入序列,构造BST
如果是合法的镜像BST前缀,按照次作为插入序列,构造镜像BST
- 跟据构造好的BST/镜像BST 求其后根遍历
[代码]
1 | ///还是只能过部分测试样例,==,害,好难嗷 |
涉及的数据结构知识点:
BST
如何跟据插入序列构建一个BST树
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27struct Node{
int val;
Node* left;
Node* right;
Node(int v):val(v),left(nullptr),right(nullptr){};
};
void insert(Node*& root,int val){//注意这里是引用
if(root==nullptr){
root = new Node(val);
}
else{
if(val<root->val){
insert(root->left, val);//插入左子树
}else{
insert(root->right,val);
}
}
}
Node* creatBST(int nodes[],int size){
Node* root = nullptr;
for(int i=0;i<size;i++){
insert(root,nodes[i]);
}
return root;
}- (构建一个镜像BST树的方法是相同的,在镜像BST中,右子树都小于根, 左子树都大于等于根)
- 可以把BST的先根遍历做为插入序列构造BST,得到的BST的先根遍历序列和之前的一样
BST的中根遍历序列是递增的
BST的删除操作
//核心思想:如果N为要删除的结点, 用结点N的前驱Pre 或者 后继 next 来替换N
//前驱为BST树中左子树最右的结点
//后继为BST树中右子树最左的结点
删除值为X的结点
1.当前root为空,说明不存在值为x的结点,直接返回
2.如果当前root的权值恰好为给定的权值x,root即为我们要删除的结点
1)如果root不存在左右孩子(叶子),则直接删除.
2)如果root只存在左子树,则用它的前驱pre覆盖root,在左子树中删除结点pre
3)如果root存在左右子树,则在右子树中寻找后继next,然后让next覆盖root,接着在左子树中删除pre
3.如果当前root的值大于给定的权值x,从root的左子树中寻找要删除的结点
4.如果当前root的值小于给定的权值x,从root的右子树寻找
1 | Node* findMax(Node* root){ |