1. 二叉排序树
2. 平衡树——AVL
(1) 定义:满足如下条件的树:
a. 是二叉查找树
b. 每个节点的左子树和右子树的高度差最多为1
(2) 平衡因子:一个结点的左子树的高度减去右子树的高度,可取-1、0、1三种值
3. 表达式树
二叉排序树
二叉排序树:中序遍历有序的二叉树
二叉搜索树、二叉查找树(BST)
操作:插入、删除、查找时间复杂度
O
(
h
)
O(h)
O(h)
二叉排序树
你需要写一种数据结构,来维护一些数,其中需要提供以下操作:
- 插入数值 x x x。
- 删除数值 x x x。
- 输出数值 x x x 的前驱(前驱定义为现有所有数中小于 x x x 的最大的数)。
- 输出数值 x x x 的后继(后继定义为现有所有数中大于 x x x 的最小的数)。
题目保证:
- 操作 1 1 1 插入的数值各不相同。
- 操作 2 2 2 删除的数值一定存在。
- 操作 3 3 3 和 4 4 4 的结果一定存在。
输入格式
第一行包含整数 n n n,表示共有 n n n 个操作命令。
接下来 n n n 行,每行包含两个整数 o p t opt opt 和 x x x,表示操作序号和操作数值。
输出格式
对于操作 3 , 4 3,4 3,4,每行输出一个操作结果。
数据范围
1
<
=
n
<
=
2000
1 <= n <= 2000
1<=n<=2000,
−
10000
<
=
x
<
=
10000
-10000 <= x <= 10000
−10000<=x<=10000
输入样例:
6
1 1
1 3
1 5
3 4
2 3
4 2
输出样例:
3
5
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 1e8;
struct TreeNode{
int val;
TreeNode *left, *right;
TreeNode(int _val): val(_val), left(NULL), right(NULL){}
}*root;
void insert(TreeNode* &root, int x){
if(!root) root = new TreeNode(x);
//if(x == root->val) return;
else if(x < root->val) insert(root->left, x);
else insert(root->right, x);
}
void remove(TreeNode* &root, int x){
if(!root) return;
if(x < root->val) remove(root->left, x);
else if(x > root->val) remove(root->right, x);
else{
if(!root->left && !root->right) root = NULL;
else if(!root->left) root = root->right;
else if(!root->right) root = root->left;
else{
auto p = root->left;
while(p->right) p = p->right;
root->val = p->val;
remove(root->left, p->val);
}
}
}
int get_pre(TreeNode* root, int x){
if(!root) return -INF;
if(root->val >= x) return get_pre(root->left, x);
return max(root->val, get_pre(root->right, x));
}
int get_suc(TreeNode* root, int x){
if(!root) return INF;
if(root->val <= x) return get_suc(root->right, x);
return min(root->val, get_suc(root->left, x));
}
int main(){
int n;
cin >> n;
while(n--){
int t, x;
cin >> t >> x;
if(t == 1) insert(root, x);
else if(t == 2) remove(root ,x);
else if(t == 3) cout << get_pre(root, x) << endl;
else cout << get_suc(root ,x) << endl;
}
return 0;
}
平衡树
h = O ( l o g n ) h = O(logn) h=O(logn)
平衡树的操作:左旋、右旋不改变中序遍历,对称
四种平衡情况
(没旋明白)
408的一道题
分支节点即非叶节点
解析
请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。
例如,当下列两棵表达式树作为算法的输入时:
表达式树
输出的等价中缀表达式分别为 (a+b)*(c*(-d))
和 (a*b)+(-(c-d))
。
注意:
- 树中至少包含一个运算符。
- 当运算符是负号时,左儿子为空,右儿子为需要取反的表达式。
- 树中所有叶节点的值均为非负整数。
样例:
输入:二叉树[+, 12, *, null, null, 6, 4, null, null, null, null]如下图所示:
+
/ \
12 *
/ \
6 4
输出:12+(6*4)
数据范围
给定二叉树的非空结点数量保证不超过 1000 1000 1000。
给定二叉树保证能够转化为合法的中缀表达式。
/**
* Definition for a binary tree node.
* struct TreeNode {
* string val;
* TreeNode *left;
* TreeNode *right;
* };
*/
class Solution {
public:
string dfs(TreeNode* root){
if(!root) return "";
if(!root->left && !root->right) return root->val;
return '(' + dfs(root->left) + root->val + dfs(root->right) + ')';
}
string expressionTree(TreeNode* root) {
return dfs(root->left) + root->val + dfs(root->right);
}
};