数据结构实验14-二叉平衡树和amp;B-树
A. DS查找—二叉树平衡因子
题目描述
二叉树用数组存储,将二叉树的结点数据依次自上而下,自左至右存储到数组中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点在数组中用0来表示。
计算二叉树每个结点的平衡因子,并按后序遍历的顺序输出结点的平衡因子。
--程序要求--
若使用C 只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求
输入
测试次数t
每组测试数据一行,数组元素个数n,后跟n个字符,二叉树的数组存储。
2
6 ABC00D
24 ABCD0EF0000H00000000000I
输出
对每组测试数据,按后序遍历的顺序输出树中结点的平衡因子(测试数据没有空树)
B 0
D 0
C 1
A -1
D 0
B 1
I 0
H 1
E 2
F 0
C 2
A -2
-
-
using namespace std;
-
-
int max(int a, int b)
-
{
-
if (a > b)return a;
-
else return b;
-
}
-
-
void display(int i, char* array, int* b)//递归
-
{
-
if (array[2 * i] != '0')
-
{
-
display(2 * i, array, b);
-
}
-
if (array[2 * i 1] != '0')
-
{
-
display(2 * i 1, array, b);
-
}
-
cout << array[i] << " " << b[i] << endl;//后序遍历,左子树后右子树,之后输出
-
}
-
-
-
int main()
-
{
-
int t;
-
cin >> t;
-
while (t--)
-
{
-
int n;
-
cin >> n;
-
char* array = new char[1000];//初始值都先赋值为零
-
for (int i = 0; i < 1000; i )
-
{
-
array[i] = '0';
-
}
-
int* balance = new int[1000];
-
int* depth = new int[1000];
-
for (int i = 0; i < 1000; i )
-
{
-
balance[i] = depth[i] = 0;
-
}
-
-
for (int i = 1; i <= n; i )
-
{
-
cin >> array[i];
-
}
-
-
for (int i = n; i >= 1; i--)//从后往前进行高度的计算
-
{
-
if (array[i] == '0')depth[i] = 0;
-
else depth[i] = max(depth[2 * i], depth[2 * i 1]) 1;
-
}
-
-
for (int i = 1; i <= n; i )
-
{
-
balance[i] = depth[2 * i] - depth[2 * i 1];//平衡因子的计算,左子树高度-右子树高度
-
}
-
-
display(1, array, balance);//递归
-
}
-
-
}
-
//平衡因子,字面意思,其实就是探讨左右是否平衡,如果不是,那么其中差了多少。
-
//然后规定了使用左子树的高度-右子树的高度=平衡因子,仅此而已!
-
//深度和高度在平衡二叉树中的区别就是,判断是否为平衡二叉树一般说深度,计算平衡因子一般说高度
B. DS二叉平衡树构建
题目描述
在初始为空的平衡二叉树中依次插入n个结点,请输出最终的平衡二叉树。
要求实现平衡二叉树,不可以使用各类库函数。
-
-
using namespace std;
-
-
-
-
-
-
class BiNode
-
{
-
public:
-
int key; // 关键值
-
int bf; // 平衡因子
-
BiNode *lChild, *rChild;
-
BiNode(int kValue, int bValue)
-
{
-
-
key = kValue;
-
bf = bValue;
-
lChild = NULL;
-
rChild = NULL;
-
}
-
-
~BiNode()
-
{
-
key = 0;
-
bf = 0;
-
lChild = NULL;
-
rChild = NULL;
-
}
-
};
-
-
// 二叉排序树
-
class BST
-
{
-
private:
-
BiNode *root; // 根结点指针
-
void rRotate(BiNode *&p);
-
void lRotate(BiNode *&p);
-
void leftBalance(BiNode *&t);
-
void rightBalance(BiNode *&t);
-
int insertAVL(BiNode *&t, int key, bool &taller); // 插入元素并做平衡处理
-
void inOrder(BiNode *p);
-
public:
-
BST();
-
void insertAVL(int key); // 二叉排序树插入元素
-
~BST();
-
void inOrder(); // 中序遍历
-
};
-
-
// 以p为根的二叉排序树作右旋处理
-
void BST::rRotate(BiNode *&p)
-
{
-
// 参考课本236页算法9.9
-
}
-
-
// 以p为根的二叉排序树作左旋处理
-
void BST::lRotate(BiNode *&p)
-
{
-
// 参考课本236页算法9.10
-
}
-
-
// t为根的二叉排序树作左平衡旋转处理
-
void BST::leftBalance(BiNode *&t)
-
{
-
// 参考课本238页算法9.12
-
}
-
-
// t为根的二叉排序树作右平衡旋转处理
-
void BST::rightBalance(BiNode *&t)
-
{
-
// 参考课本238页算法9.12
-
}
-
-
-
int BST::insertAVL(BiNode *&t, int key, bool &taller)
-
{
-
-
// 参考课本237页算法9.11
-
}
-
-
void BST::inOrder(BiNode *p)
-
{
-
if(p)
-
{
-
inOrder(p->lChild);
-
cout << p->key << ':' << p->bf << ' ';
-
inOrder(p->rChild);
-
}
-
-
return;
-
}
-
-
// 二叉排序树初始化
-
BST::BST()
-
{
-
root = NULL;
-
}
-
-
BST::~BST()
-
{
-
root = NULL;
-
}
-
-
// 插入元素并作平衡处理
-
void BST::insertAVL(int key)
-
{
-
bool taller = false;
-
insertAVL(root, key, taller);
-
}
-
-
-
// 中序遍历
-
void BST::inOrder()
-
{
-
inOrder(root);
-
}
-
-
int main(void)
-
{
-
int t;
-
cin >> t;
-
while(t --)
-
{
-
// 构建二叉平衡树,并在插入元素时做平衡处理
-
int n, elem;
-
cin >> n;
-
BST tree;
-
while(n --)
-
{
-
cin >> elem;
-
tree.insertAVL(elem);
-
}
-
tree.inOrder();
-
cout << endl;
-
}
-
-
return 0;
-
}
输入
第一行输入测试数据组数t;
每组测试数据,第一行输入结点数n, 第二行输入n个结点值。
8
3
64 5 1
3
64 5 13
6
64 78 5 1 13 15
6
64 78 5 1 13 10
3
64 78 100
3
64 80 70
6
64 30 80 90 70 68
6
64 30 80 90 70 75
输出
对每组测试数据,按中序遍历的顺序输出树中,结点值及平衡因子(测试数据没有空树),即结点值:平衡因子,不同结点之间间隔一个空格。
1:0 5:0 64:0
5:0 13:0 64:0
1:0 5:1 13:0 15:0 64:0 78:0
1:0 5:0 10:0 13:0 64:-1 78:0
64:0 78:0 100:0
64:0 70:0 80:0
30:0 64:0 68:0 70:0 80:-1 90:0
30:0 64:1 70:0 75:0 80:0 90:0
这道题纯粹的考察平衡二叉树的算法,非常纯粹,只需要照抄书上代码即可,但是同样有几点是需要注意的。
第一点是:输入输出问题,这题居然卡输出,main代码都给好了,居然卡输出,真是无语,但是我将中序遍历输入的那堆东西存到数组里面去了,分别是a数组和b数组,所以最后是用数组进行输出便于格式正确。
第二点是insertavl函数里太多弯弯绕绕了,容易看花眼,所以一定要小心检查。
第三点是insertavl函数里有个new t,注意看清楚自己的构造函数不要再傻傻的new了
-
-
using namespace std;
-
-
-
-
-
int a[1000];
-
int b[1000];
-
int z;
-
-
-
class BiNode
-
{
-
public:
-
int key; // 关键值
-
int bf; // 平衡因子
-
BiNode* lChild, * rChild;
-
BiNode(int kValue, int bValue)
-
{
-
-
key = kValue;
-
bf = bValue;
-
lChild = NULL;
-
rChild = NULL;
-
}
-
-
~BiNode()
-
{
-
key = 0;
-
bf = 0;
-
lChild = NULL;
-
rChild = NULL;
-
}
-
};
-
-
// 二叉排序树
-
class BST
-
{
-
private:
-
BiNode* root; // 根结点指针
-
void rRotate(BiNode*& p);
-
void lRotate(BiNode*& p);
-
void leftBalance(BiNode*& t);
-
void rightBalance(BiNode*& t);
-
int insertAVL(BiNode*& t, int key, bool& taller); // 插入元素并做平衡处理
-
void inOrder(BiNode* p);
-
public:
-
BST();
-
void insertAVL(int key); // 二叉排序树插入元素
-
~BST();
-
void inOrder(); // 中序遍历
-
};
-
-
// 以p为根的二叉排序树作右旋处理
-
void BST::rRotate(BiNode*& p)
-
{
-
// 参考课本236页算法9.9
-
BiNode* lc;//建立一个新的节点
-
lc = p->lChild;//lc指向的*p的左子树根节点
-
p->lChild = lc->rChild;//lc的左子树挂接为*p的左子树
-
lc->rChild = p;
-
p = lc;//p指向新的节点
-
-
}
-
-
// 以p为根的二叉排序树作左旋处理
-
void BST::lRotate(BiNode*& p)
-
{
-
// 参考课本236页算法9.10
-
BiNode* rc;
-
rc = p->rChild;//rc指向的*p的右子树根节点
-
p->rChild = rc->lChild;
-
rc->lChild = p;
-
p = rc;
-
}
-
-
// t为根的二叉排序树作左平衡旋转处理
-
void BST::leftBalance(BiNode*& t)
-
{
-
// 参考课本238页算法9.12
-
BiNode* lc;
-
lc = t->lChild;
-
switch (lc->bf)
-
{
-
case LH:
-
t->bf = lc->bf = EH;
-
rRotate(t);
-
break;
-
case RH:
-
BiNode* rd;
-
rd = lc->rChild;
-
switch (rd->bf)
-
{
-
case LH:
-
t->bf = RH;
-
lc->bf = EH;
-
break;
-
case EH:
-
t->bf = lc->bf = EH;
-
break;
-
case RH:
-
t->bf = EH;
-
lc->bf = LH;
-
break;
-
}
-
rd->bf = EH;
-
lRotate(t->lChild);
-
rRotate(t);
-
}
-
}
-
-
// t为根的二叉排序树作右平衡旋转处理
-
void BST::rightBalance(BiNode*& t)
-
{
-
// 参考课本238页算法9.12
-
//对指针T所致节点为根的二叉树作平衡旋转处理
-
BiNode* rc;
-
-
rc = t->rChild;
-
//检查T节点的右孩子,根据其平衡因子判断是左旋还是右左双旋
-
switch (rc->bf)
-
{
-
//右孩子的平衡因子为-1,平衡因子是直线,左旋
-
case RH:
-
t->bf = EH;
-
rc->bf = EH;
-
lRotate(t);
-
break;
-
//右孩子平衡因子为-1,平衡因子为折线,右左双旋
-
case LH:
-
BiNode* ld;
-
ld = rc->lChild;
-
//修改T节点和其右孩子的平衡因子
-
switch (ld->bf)
-
{
-
case LH:
-
t->bf = EH;
-
rc->bf = RH;
-
break;
-
case EH:
-
t->bf = rc->bf = EH;
-
break;
-
case RH:
-
t->bf = LH;
-
rc->bf = EH;
-
break;
-
}
-
ld->bf = EH;
-
rRotate(t->rChild);
-
lRotate(t);
-
}
-
}
-
-
-
int BST::insertAVL(BiNode*& t, int key, bool& taller)
-
{
-
-
// 参考课本237页算法9.11
-
if (!t)
-
{
-
t = new BiNode(key, EH);
-
taller = true;
-
}
-
else
-
{
-
if (t->key==key)
-
{
-
taller = false;
-
return 0;
-
}
-
-
if (key < t->key)
-
{
-
if (!insertAVL(t->lChild, key, taller)) {
-
taller = false;
-
return 0;
-
}
-
if (taller)
-
{
-
switch (t->bf)
-
{
-
case LH:
-
leftBalance(t);
-
taller = false;
-
break;
-
case EH:
-
t->bf = LH;
-
taller = true;
-
break;
-
case RH:
-
t->bf = EH;
-
taller = false;
-
break;
-
}
-
}
-
}
-
else
-
{
-
if (!insertAVL(t->rChild, key, taller))
-
{
-
taller = false;
-
return 0;
-
}
-
if (taller)
-
{
-
switch (t->bf)
-
{
-
case LH:
-
t->bf = EH;
-
taller = false;
-
break;
-
case EH:
-
t->bf = RH;
-
taller = true;
-
break;
-
case RH:
-
rightBalance(t);
-
taller = false;
-
break;
-
}
-
}
-
}
-
}
-
return 1;
-
}
-
-
void BST::inOrder(BiNode* p)
-
{
-
if (p)
-
{
-
inOrder(p->lChild);
-
//cout << p->key << ':' << p->bf << ' ';
-
a[z] = p->key;
-
b[z] = p->bf;
-
z ;
-
inOrder(p->rChild);
-
}
-
-
return;
-
}
-
-
// 二叉排序树初始化
-
BST::BST()
-
{
-
root = NULL;
-
}
-
-
BST::~BST()
-
{
-
root = NULL;
-
}
-
-
// 插入元素并作平衡处理
-
void BST::insertAVL(int key)
-
{
-
bool taller = false;
-
insertAVL(root, key, taller);
-
}
-
-
-
// 中序遍历
-
void BST::inOrder()
-
{
-
inOrder(root);
-
}
-
-
int main(void)
-
{
-
int t;
-
cin >> t;
-
while (t--)
-
{
-
// 构建二叉平衡树,并在插入元素时做平衡处理
-
int n, elem;
-
cin >> n;
-
BST tree;
-
int n1 = n;
-
while (n--)
-
{
-
cin >> elem;
-
tree.insertAVL(elem);
-
}
-
tree.inOrder();
-
for (int i = 0; i < n1; i )
-
{
-
cout << a[i] << ":" << b[i];
-
if (i != n1 - 1)
-
cout << " ";
-
if(t)
-
cout << endl;
-
z = 0;
-
}
-
-
return 0;
-
}
C. 二叉平衡树练习
题目描述
对二叉平衡树进行四种操作:
1 D K
表示插入一个新数据,数据为D
用于输出,关键值为K
用于排序;2
输出当前树中最大关键值所带的数据,并删除该数据,如果没有这个关键值,则输出0
;3
输出当前树中最小关键值所带的数据,并删除该数据,如果没有这个关键值,则输出0
;4 K
输出关键值为K
的数据,并删除该数据,如果没有这个关键值,则输出0
。
要求必须实现平衡树,不可以使用各类库函数
AVL代码模板参考:
-
-
const int maxn = 1e5 10;
-
struct Node
-
{
-
int key; // 关键值
-
int data; // 携带的数据
-
int left; // 左子树地址(数组下标)
-
int right; // 右子树地址(数组下标)
-
int height; // 当前结点为根的子树高度
-
void Init(){data = key = left = right = height = -1;}
-
void Init(int k_, int d_=0){Init(); key = k_; data = d_;}
-
Node(){Init();}
-
Node(int k_, int d_=0){Init(k_, d_);}
-
};
-
-
Node tr[maxn];
-
int root, tp; // root标记根节点位置,tp全局结点分配下标
-
-
inline int UpdateHeight(int now)
-
{
-
// 更新 tr[now] 结点的子树高度,即tr[now].height的值
-
}
-
inline int HeightDiff(int now)
-
{
-
// 计算 tr[now] 结点的平衡因子
-
}
-
int LL(int an)
-
{
-
}
-
int RR(int an)
-
{
-
}
-
int LR(int an)
-
{
-
}
-
int RL(int an)
-
{
-
}
-
void Insert(int &now, int key, int data=0)
-
{
-
if(now == -1)
-
{
-
// 传入指针为空,新建结点保存数据
-
now = tp;
-
tr[now].Init(key, data);
-
}
-
// 判断插入哪个子树,插入数据,判断平衡因子,做正确旋转,更新高度
-
}
-
void Delete(int &now, int key)
-
{
-
if(now == -1) return;
-
else if(key < tr[now].key) Delete(tr[now].left, key);
-
else if(key > tr[now].key) Delete(tr[now].right, key);
-
else
-
{
-
// 删除当前结点
-
}
-
// 处理树平衡
-
}
-
-
int main()
-
{
-
int n, op, key, data;
-
while(scanf("%d", &n) != EOF)
-
{
-
for(root = tp = -1; n --; ) // 初始化根结点和“内存指针”
-
{
-
scanf("%d", &op);
-
if(op == 1)
-
{
-
}
-
else if(op == 2)
-
{
-
}
-
else if(op == 3)
-
{
-
}
-
else
-
{
-
}
-
}
-
return 0;
-
}
输入
每组数据第一行n
表示有n
个操作
接下来n
行操作内容
8
2
1 20 14
1 30 3
2
1 10 99
3
2
2
输出
按操作规则输出对应内容
0
20
30
10
0
-
-
-
-
using namespace std;
-
-
int Max(int a, int b)
-
{
-
if (a<b)
-
{
-
return b;
-
}
-
else
-
{
-
return a;
-
}
-
}
-
const int maxn = 1e5 10;
-
struct Node
-
{
-
int key; // 关键值
-
int data; // 携带的数据
-
int left; // 左子树地址(数组下标)
-
int right; // 右子树地址(数组下标)
-
int height; // 当前结点为根的子树高度
-
void Init() { data = key = left = right = height = -1; }
-
void Init(int k_, int d_ = 0) { Init(); key = k_; data = d_; }
-
Node() { Init(); }
-
Node(int k_, int d_ = 0) { Init(k_, d_); }
-
};
-
-
Node tr[maxn];
-
int root, tp; // root标记根节点位置,tp全局结点分配下标
-
-
inline int UpdateHeight(int now)
-
{
-
// 更新 tr[now] 结点的子树高度,即tr[now].height的值
-
return tr[now].height = Max(tr[tr[now].left].height, tr[tr[now].right].height) 1;
-
}
-
inline int HeightDiff(int now)
-
{
-
// 计算 tr[now] 结点的平衡因子
-
return tr[tr[now].left].height - tr[tr[now].right].height;
-
}
-
int LL(int an)
-
{
-
int bn = tr[an].left;
-
tr[an].left = tr[bn].right;
-
tr[bn].right = an;
-
UpdateHeight(an);
-
UpdateHeight(bn);
-
return bn;
-
}
-
int RR(int an)
-
{
-
int bn = tr[an].right;
-
tr[an].right = tr[bn].left;
-
tr[bn].left = an;
-
UpdateHeight(an);
-
UpdateHeight(bn);
-
return bn;
-
}
-
int LR(int an)
-
{
-
tr[an].left = RR(tr[an].left);
-
return LL(an);
-
}
-
int RL(int an)
-
{
-
tr[an].right = LL(tr[an].right);
-
return RR(an);
-
}
-
void Insert(int& now, int key, int data = 0)
-
{
-
if (now == -1)
-
{
-
// 传入指针为空,新建结点保存数据
-
now = tp;
-
tr[now].Init(key, data);
-
}
-
// 判断插入哪个子树,插入数据,判断平衡因子,做正确旋转,更新高度
-
else if (key < tr[now].key)
-
{
-
Insert(tr[now].left, key, data);
-
if (HeightDiff(now) == 2)
-
{
-
if (key < tr[tr[now].left].key) now = LL(now);
-
else now = LR(now);
-
}
-
}
-
else if (key > tr[now].key)
-
{
-
Insert(tr[now].right, key, data);
-
if (HeightDiff(now) == -2)
-
{
-
if (key > tr[tr[now].right].key) now = RR(now);
-
else now = RL(now);
-
}
-
}
-
-
UpdateHeight(now);
-
}
-
-
int FindMax(int now)
-
{
-
if (tr[now].right == 0)return -1;
-
while (tr[now].right != -1) now = tr[now].right;
-
return now;
-
}
-
-
int FindMin(int now)
-
{
-
if (tr[now].left == 0)return -1;
-
while (tr[now].left != -1) now = tr[now].left;
-
return now;
-
}
-
void Delete(int& now, int key)
-
{
-
if (now == -1) return;
-
else if (key < tr[now].key) Delete(tr[now].left, key);
-
else if (key > tr[now].key) Delete(tr[now].right, key);
-
else
-
{
-
// 删除当前结点
-
-
if (tr[now].left == -1 && tr[now].right == -1)
-
{
-
now = -1;
-
return;
-
}
-
else if (tr[now].left != -1 && tr[now].right == -1)
-
{
-
now = tr[now].left;
-
return;
-
}
-
else if (tr[now].left == -1 && tr[now].right != -1)
-
{
-
now = tr[now].right;
-
return;
-
}
-
else
-
{
-
int maxLeftIndex = FindMax(tr[now].left);
-
swap(tr[now].key, tr[maxLeftIndex].key);
-
swap(tr[now].data, tr[maxLeftIndex].data);
-
Delete(tr[now].left, tr[maxLeftIndex].key);
-
if (HeightDiff(now) == 2)
-
{
-
if (HeightDiff(tr[now].left) >= 0) now = LL(now);
-
else now = LR(now);
-
}
-
UpdateHeight(now);
-
}
-
}
-
// 处理树平衡
-
if (HeightDiff(now) == 2)
-
{
-
if (HeightDiff(tr[now].left) >= 0) now = LL(now);
-
else now = LR(now);
-
}
-
else if (HeightDiff(now) == -2)
-
{
-
if (HeightDiff(tr[now].right) <= 0) now = RR(now);
-
else now = RL(now);
-
}
-
UpdateHeight(now);
-
}
-
-
void InorderTraversal(int now, vector<int>& res)
-
{
-
if (now == -1) return;
-
InorderTraversal(tr[now].left, res);
-
res.push_back(tr[now].key);
-
InorderTraversal(tr[now].right, res);
-
}
-
-
-
int main()
-
{
-
int n, op, key, data;
-
while (scanf("%d", &n) != EOF)
-
{
-
for (root = tp = -1; n--; ) // 初始化根结点和“内存指针”
-
{
-
scanf("%d", &op);
-
if (op == 1)
-
{
-
scanf("%d%d", &data, &key);
-
Insert(root, key, data);
-
-
}
-
else if (op == 2)
-
{
-
int maxNodeIndex = FindMax(root);
-
if (maxNodeIndex == -1 || tr[maxNodeIndex].data < 0)
-
{
-
printf("0\n");
-
}
-
else
-
{
-
printf("%d\n", tr[maxNodeIndex].data);
-
Delete(root, tr[maxNodeIndex].key);
-
}
-
}
-
else if (op == 3)
-
{
-
int minNodeIndex = FindMin(root);
-
if (minNodeIndex == -1 || tr[minNodeIndex].data < 0)
-
{
-
printf("0\n");
-
}
-
else
-
{
-
printf("%d\n", tr[minNodeIndex].data);
-
Delete(root, tr[minNodeIndex].key);
-
}
-
}
-
else
-
{
-
scanf("%d", &key);
-
int nodeIndex = root;
-
while (nodeIndex != -1 && tr[nodeIndex].key != key)
-
{
-
if (tr[nodeIndex].key < key)
-
{
-
nodeIndex = tr[nodeIndex].right;
-
}
-
else
-
{
-
nodeIndex = tr[nodeIndex].left;
-
}
-
}
-
if (nodeIndex == -1 || tr[nodeIndex].data < 0)
-
{
-
printf("0\n");
-
}
-
else
-
{
-
printf("%d\n", tr[nodeIndex].data);
-
Delete(root, key);
-
}
-
}
-
}
-
}
-
return 0;
-
}
D. 平衡树上的第k小
题目描述
二种操作:
1 Key
表示插入一个新数据Key
;2 K
输出当前数据从小到大排列的第K
个数,并删除这个数,不存在则输出-1
。
要求使用平衡树实现
输入
每组数据第一行n
表示有n
个操作
接下来n
行操作内容
1 <= n <= 10^5
8
1 1
1 2
1 3
1 4
1 5
2 2
2 2
2 6
输出
按操作规则输出对应内容
2
3
-1
-
-
using namespace std;
-
-
struct TreeNode {
-
int key, height, size;
-
TreeNode *left, *right;
-
TreeNode(int k) : key(k), height(1), size(1), left(nullptr), right(nullptr) {}
-
};
-
-
int height(TreeNode *node) {
-
return node ? node->height : 0;
-
}
-
-
int balanceFactor(TreeNode *node) {
-
return height(node->right) - height(node->left);
-
}
-
-
void updateHeightAndSize(TreeNode *node) {
-
node->height = max(height(node->left), height(node->right)) 1;
-
node->size = (node->left ? node->left->size : 0) (node->right ? node->right->size : 0) 1;
-
}
-
-
void rotateRight(TreeNode *&node) {
-
TreeNode *left = node->left;
-
node->left = left->right;
-
left->right = node;
-
updateHeightAndSize(node);
-
updateHeightAndSize(left);
-
node = left;
-
}
-
-
void rotateLeft(TreeNode *&node) {
-
TreeNode *right = node->right;
-
node->right = right->left;
-
right->left = node;
-
updateHeightAndSize(node);
-
updateHeightAndSize(right);
-
node = right;
-
}
-
-
void balance(TreeNode *&node) {
-
if (balanceFactor(node) == 2) {
-
if (balanceFactor(node->right) < 0) {
-
rotateRight(node->right);
-
}
-
rotateLeft(node);
-
} else if (balanceFactor(node) == -2) {
-
if (balanceFactor(node->left) > 0) {
-
rotateLeft(node->left);
-
}
-
rotateRight(node);
-
}
-
updateHeightAndSize(node);
-
}
-
-
void insert(TreeNode *&node, int key) {
-
if (!node) {
-
node = new TreeNode(key);
-
} else if (key < node->key) {
-
insert(node->left, key);
-
} else if (key > node->key) {
-
insert(node->right, key);
-
}
-
balance(node);
-
}
-
-
int getKth(TreeNode *&node, int k) {
-
int r = (node->left ? node->left->size : 0) 1;
-
if (k == r) {
-
int res = node->key;
-
if (!node->left && !node->right) {
-
delete node;
-
node = nullptr;
-
} else if (node->left && !node->right) {
-
TreeNode *tmp = node;
-
node = node->left;
-
delete tmp;
-
} else if (!node->left && node->right) {
-
TreeNode *tmp = node;
-
node = node->right;
-
delete tmp;
-
} else {
-
TreeNode *p = node->right;
-
while (p->left) {
-
p = p->left;
-
}
-
node->key = p->key;
-
getKth(node->right, 1);
-
}
-
return res;
-
} else if (k < r) {
-
return getKth(node->left, k);
-
} else {
-
return getKth(node->right, k - r);
-
}
-
}
-
-
int main() {
-
int n;
-
cin >> n;
-
-
TreeNode *root = nullptr;
-
for (int i = 0; i < n; i ) {
-
int op, k;
-
cin >> op >> k;
-
-
if (op == 1) { // 插入操作
-
insert(root, k);
-
} else if (op == 2) { // 查找并删除第 k 小的元素
-
if (root && root->size >= k) {
-
cout << getKth(root, k) << endl;
-
} else {
-
cout << -1 << endl;
-
}
-
}
-
}
-
-
return 0;
-
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggfgib
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13