你需要写一种数据结构,来维护一些数,其中需要提供以下操作:
- 插入数值 $x$。
- 删除数值 $x$。
题目保证:
- 操作 $1$ 插入的数值各不相同。
- 操作 $2$ 删除的数值一定存在。
输出树的前序遍历
输入格式
第一行包含整数 $n$,表示共有 $n$ 个操作命令。
接下来 $n$ 行,每行包含两个整数 $opt$ 和 $x$,表示操作序号和操作数值。
数据范围
$1 \le n \le 2000$,
$-10000 \le x \le 10000$
输入样例:
4
1 1
1 3
1 5
2 3
输出样例:
1 5
思路
插入操作:
删除操作:
对于一个二叉排序树来说,中序遍历(左中右)是有序的。
有三种情况
- 该节点为叶节点
- 该节点存在一个左节点,或者一个右节点
- 该节点存在左节点、右节点
重点说明一下第三种情况:由于是一颗二叉排序树,故节点$X$的左子树中最右的根节点$A$一定是左子树中最大的值,故将节点$A$的值赋值给节点$X$,再递归遍历左子树,删除节点$A$。
Code
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include <iostream> #include <cstring> #include <algorithm> #include <queue>
using namespace std;
struct TreeNode { int val; TreeNode *left, *right; TreeNode(int _val): val(_val), left(NULL), right(NULL) {} };
int n;
void insert(TreeNode* &root, int x) { if(root == NULL) root = new TreeNode(x); else if(root->val > x) insert(root->left, x); else insert(root->right, x); }
void remove(TreeNode* &root, int x) { if(root == NULL) return; if(root->val > x) remove(root->left, x); else if(root->val < x) remove(root->right, x); else { if(root->left == NULL && root->right == NULL) root = NULL; else if(root->left == NULL) root = root->right; else if(root->right == NULL) root = root->left; else { auto p = root->left; while(p->right != NULL) p = p->right; swap(root->val, p->val); remove(root->left, p->val); } } }
void print(TreeNode *root) { queue<TreeNode*> q; if(root != NULL) q.push(root); while(q.size()) { auto t = q.front(); q.pop(); cout << t->val << " "; if(t->left != NULL || t->right != NULL) { if(t->left) q.push(t->left); if(t->right) q.push(t->right); } } } int main() { TreeNode* root; cin >> n; while(n -- ) { int opt, x; cin >> opt >> x; if(opt == 1) insert(root, x); else if(opt == 2) remove(root, x); } print(root); return 0; }
|