【5】二叉排序树、平衡树、表达式树

1. 二叉排序树
2. 平衡树——AVL
   (1) 定义:满足如下条件的树:
   	a. 是二叉查找树
   	b. 每个节点的左子树和右子树的高度差最多为1
   (2) 平衡因子:一个结点的左子树的高度减去右子树的高度,可取-1、0、1三种值
3. 表达式树

二叉排序树

二叉排序树:中序遍历有序的二叉树
二叉搜索树、二叉查找树(BST)
操作:插入、删除、查找时间复杂度 O ( h ) O(h) O(h)

二叉排序树
你需要写一种数据结构,来维护一些数,其中需要提供以下操作:

  1. 插入数值 x x x
  2. 删除数值 x x x
  3. 输出数值 x x x 的前驱(前驱定义为现有所有数中小于 x x x 的最大的数)。
  4. 输出数值 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的一道题
在这里插入图片描述
分支节点即非叶节点
解析
在这里插入图片描述

请设计一个算法,将给定的表达式树(二叉树)转换为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。

例如,当下列两棵表达式树作为算法的输入时:

QQ截图20210708095213.png

表达式树
输出的等价中缀表达式分别为 (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);
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值