当前位置:   article > 正文

数据结构实验14-二叉平衡树&B-树_在初始为空的平衡二叉树中依次插入n个结点,请输出最终的平衡二叉树。 要求实现平

在初始为空的平衡二叉树中依次插入n个结点,请输出最终的平衡二叉树。 要求实现平

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
 

  1. #include <iostream>
  2. using namespace std;
  3. int max(int a, int b)
  4. {
  5. if (a > b)return a;
  6. else return b;
  7. }
  8. void display(int i, char* array, int* b)//递归
  9. {
  10. if (array[2 * i] != '0')
  11. {
  12. display(2 * i, array, b);
  13. }
  14. if (array[2 * i + 1] != '0')
  15. {
  16. display(2 * i + 1, array, b);
  17. }
  18. cout << array[i] << " " << b[i] << endl;//后序遍历,左子树后右子树,之后输出
  19. }
  20. int main()
  21. {
  22. int t;
  23. cin >> t;
  24. while (t--)
  25. {
  26. int n;
  27. cin >> n;
  28. char* array = new char[1000];//初始值都先赋值为零
  29. for (int i = 0; i < 1000; i++)
  30. {
  31. array[i] = '0';
  32. }
  33. int* balance = new int[1000];
  34. int* depth = new int[1000];
  35. for (int i = 0; i < 1000; i++)
  36. {
  37. balance[i] = depth[i] = 0;
  38. }
  39. for (int i = 1; i <= n; i++)
  40. {
  41. cin >> array[i];
  42. }
  43. for (int i = n; i >= 1; i--)//从后往前进行高度的计算
  44. {
  45. if (array[i] == '0')depth[i] = 0;
  46. else depth[i] = max(depth[2 * i], depth[2 * i + 1]) + 1;
  47. }
  48. for (int i = 1; i <= n; i++)
  49. {
  50. balance[i] = depth[2 * i] - depth[2 * i + 1];//平衡因子的计算,左子树高度-右子树高度
  51. }
  52. display(1, array, balance);//递归
  53. }
  54. }
  55. //平衡因子,字面意思,其实就是探讨左右是否平衡,如果不是,那么其中差了多少。
  56. //然后规定了使用左子树的高度-右子树的高度=平衡因子,仅此而已!
  57. //深度和高度在平衡二叉树中的区别就是,判断是否为平衡二叉树一般说深度,计算平衡因子一般说高度

B. DS二叉平衡树构建

题目描述

初始为空的平衡二叉树中依次插入n个结点,请输出最终的平衡二叉树。

要求实现平衡二叉树,不可以使用各类库函数。

  1. #include <iostream>
  2. using namespace std;
  3. #define LH 1 // 左高
  4. #define EH 0 // 等高
  5. #define RH -1 // 右高
  6. class BiNode
  7. {
  8. public:
  9. int key; // 关键值
  10. int bf; // 平衡因子
  11. BiNode *lChild, *rChild;
  12. BiNode(int kValue, int bValue)
  13. {
  14. key = kValue;
  15. bf = bValue;
  16. lChild = NULL;
  17. rChild = NULL;
  18. }
  19. ~BiNode()
  20. {
  21. key = 0;
  22. bf = 0;
  23. lChild = NULL;
  24. rChild = NULL;
  25. }
  26. };
  27. // 二叉排序树
  28. class BST
  29. {
  30. private:
  31. BiNode *root; // 根结点指针
  32. void rRotate(BiNode *&p);
  33. void lRotate(BiNode *&p);
  34. void leftBalance(BiNode *&t);
  35. void rightBalance(BiNode *&t);
  36. int insertAVL(BiNode *&t, int key, bool &taller); // 插入元素并做平衡处理
  37. void inOrder(BiNode *p);
  38. public:
  39. BST();
  40. void insertAVL(int key); // 二叉排序树插入元素
  41. ~BST();
  42. void inOrder(); // 中序遍历
  43. };
  44. // 以p为根的二叉排序树作右旋处理
  45. void BST::rRotate(BiNode *&p)
  46. {
  47. // 参考课本236页算法9.9
  48. }
  49. // 以p为根的二叉排序树作左旋处理
  50. void BST::lRotate(BiNode *&p)
  51. {
  52. // 参考课本236页算法9.10
  53. }
  54. // t为根的二叉排序树作左平衡旋转处理
  55. void BST::leftBalance(BiNode *&t)
  56. {
  57. // 参考课本238页算法9.12
  58. }
  59. // t为根的二叉排序树作右平衡旋转处理
  60. void BST::rightBalance(BiNode *&t)
  61. {
  62. // 参考课本238页算法9.12
  63. }
  64. int BST::insertAVL(BiNode *&t, int key, bool &taller)
  65. {
  66. // 参考课本237页算法9.11
  67. }
  68. void BST::inOrder(BiNode *p)
  69. {
  70. if(p)
  71. {
  72. inOrder(p->lChild);
  73. cout << p->key << ':' << p->bf << ' ';
  74. inOrder(p->rChild);
  75. }
  76. return;
  77. }
  78. // 二叉排序树初始化
  79. BST::BST()
  80. {
  81. root = NULL;
  82. }
  83. BST::~BST()
  84. {
  85. root = NULL;
  86. }
  87. // 插入元素并作平衡处理
  88. void BST::insertAVL(int key)
  89. {
  90. bool taller = false;
  91. insertAVL(root, key, taller);
  92. }
  93. // 中序遍历
  94. void BST::inOrder()
  95. {
  96. inOrder(root);
  97. }
  98. int main(void)
  99. {
  100. int t;
  101. cin >> t;
  102. while(t --)
  103. {
  104. // 构建二叉平衡树,并在插入元素时做平衡处理
  105. int n, elem;
  106. cin >> n;
  107. BST tree;
  108. while(n --)
  109. {
  110. cin >> elem;
  111. tree.insertAVL(elem);
  112. }
  113. tree.inOrder();
  114. cout << endl;
  115. }
  116. return 0;
  117. }

输入

第一行输入测试数据组数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了

  1. #include <iostream>
  2. using namespace std;
  3. #define LH +1 // 左高
  4. #define EH 0 // 等高
  5. #define RH -1 // 右高
  6. int a[1000];
  7. int b[1000];
  8. int z;
  9. class BiNode
  10. {
  11. public:
  12. int key; // 关键值
  13. int bf; // 平衡因子
  14. BiNode* lChild, * rChild;
  15. BiNode(int kValue, int bValue)
  16. {
  17. key = kValue;
  18. bf = bValue;
  19. lChild = NULL;
  20. rChild = NULL;
  21. }
  22. ~BiNode()
  23. {
  24. key = 0;
  25. bf = 0;
  26. lChild = NULL;
  27. rChild = NULL;
  28. }
  29. };
  30. // 二叉排序树
  31. class BST
  32. {
  33. private:
  34. BiNode* root; // 根结点指针
  35. void rRotate(BiNode*& p);
  36. void lRotate(BiNode*& p);
  37. void leftBalance(BiNode*& t);
  38. void rightBalance(BiNode*& t);
  39. int insertAVL(BiNode*& t, int key, bool& taller); // 插入元素并做平衡处理
  40. void inOrder(BiNode* p);
  41. public:
  42. BST();
  43. void insertAVL(int key); // 二叉排序树插入元素
  44. ~BST();
  45. void inOrder(); // 中序遍历
  46. };
  47. // 以p为根的二叉排序树作右旋处理
  48. void BST::rRotate(BiNode*& p)
  49. {
  50. // 参考课本236页算法9.9
  51. BiNode* lc;//建立一个新的节点
  52. lc = p->lChild;//lc指向的*p的左子树根节点
  53. p->lChild = lc->rChild;//lc的左子树挂接为*p的左子树
  54. lc->rChild = p;
  55. p = lc;//p指向新的节点
  56. }
  57. // 以p为根的二叉排序树作左旋处理
  58. void BST::lRotate(BiNode*& p)
  59. {
  60. // 参考课本236页算法9.10
  61. BiNode* rc;
  62. rc = p->rChild;//rc指向的*p的右子树根节点
  63. p->rChild = rc->lChild;
  64. rc->lChild = p;
  65. p = rc;
  66. }
  67. // t为根的二叉排序树作左平衡旋转处理
  68. void BST::leftBalance(BiNode*& t)
  69. {
  70. // 参考课本238页算法9.12
  71. BiNode* lc;
  72. lc = t->lChild;
  73. switch (lc->bf)
  74. {
  75. case LH:
  76. t->bf = lc->bf = EH;
  77. rRotate(t);
  78. break;
  79. case RH:
  80. BiNode* rd;
  81. rd = lc->rChild;
  82. switch (rd->bf)
  83. {
  84. case LH:
  85. t->bf = RH;
  86. lc->bf = EH;
  87. break;
  88. case EH:
  89. t->bf = lc->bf = EH;
  90. break;
  91. case RH:
  92. t->bf = EH;
  93. lc->bf = LH;
  94. break;
  95. }
  96. rd->bf = EH;
  97. lRotate(t->lChild);
  98. rRotate(t);
  99. }
  100. }
  101. // t为根的二叉排序树作右平衡旋转处理
  102. void BST::rightBalance(BiNode*& t)
  103. {
  104. // 参考课本238页算法9.12
  105. //对指针T所致节点为根的二叉树作平衡旋转处理
  106. BiNode* rc;
  107. rc = t->rChild;
  108. //检查T节点的右孩子,根据其平衡因子判断是左旋还是右左双旋
  109. switch (rc->bf)
  110. {
  111. //右孩子的平衡因子为-1,平衡因子是直线,左旋
  112. case RH:
  113. t->bf = EH;
  114. rc->bf = EH;
  115. lRotate(t);
  116. break;
  117. //右孩子平衡因子为-1,平衡因子为折线,右左双旋
  118. case LH:
  119. BiNode* ld;
  120. ld = rc->lChild;
  121. //修改T节点和其右孩子的平衡因子
  122. switch (ld->bf)
  123. {
  124. case LH:
  125. t->bf = EH;
  126. rc->bf = RH;
  127. break;
  128. case EH:
  129. t->bf = rc->bf = EH;
  130. break;
  131. case RH:
  132. t->bf = LH;
  133. rc->bf = EH;
  134. break;
  135. }
  136. ld->bf = EH;
  137. rRotate(t->rChild);
  138. lRotate(t);
  139. }
  140. }
  141. int BST::insertAVL(BiNode*& t, int key, bool& taller)
  142. {
  143. // 参考课本237页算法9.11
  144. if (!t)
  145. {
  146. t = new BiNode(key, EH);
  147. taller = true;
  148. }
  149. else
  150. {
  151. if (t->key==key)
  152. {
  153. taller = false;
  154. return 0;
  155. }
  156. if (key < t->key)
  157. {
  158. if (!insertAVL(t->lChild, key, taller)) {
  159. taller = false;
  160. return 0;
  161. }
  162. if (taller)
  163. {
  164. switch (t->bf)
  165. {
  166. case LH:
  167. leftBalance(t);
  168. taller = false;
  169. break;
  170. case EH:
  171. t->bf = LH;
  172. taller = true;
  173. break;
  174. case RH:
  175. t->bf = EH;
  176. taller = false;
  177. break;
  178. }
  179. }
  180. }
  181. else
  182. {
  183. if (!insertAVL(t->rChild, key, taller))
  184. {
  185. taller = false;
  186. return 0;
  187. }
  188. if (taller)
  189. {
  190. switch (t->bf)
  191. {
  192. case LH:
  193. t->bf = EH;
  194. taller = false;
  195. break;
  196. case EH:
  197. t->bf = RH;
  198. taller = true;
  199. break;
  200. case RH:
  201. rightBalance(t);
  202. taller = false;
  203. break;
  204. }
  205. }
  206. }
  207. }
  208. return 1;
  209. }
  210. void BST::inOrder(BiNode* p)
  211. {
  212. if (p)
  213. {
  214. inOrder(p->lChild);
  215. //cout << p->key << ':' << p->bf << ' ';
  216. a[z] = p->key;
  217. b[z] = p->bf;
  218. z++;
  219. inOrder(p->rChild);
  220. }
  221. return;
  222. }
  223. // 二叉排序树初始化
  224. BST::BST()
  225. {
  226. root = NULL;
  227. }
  228. BST::~BST()
  229. {
  230. root = NULL;
  231. }
  232. // 插入元素并作平衡处理
  233. void BST::insertAVL(int key)
  234. {
  235. bool taller = false;
  236. insertAVL(root, key, taller);
  237. }
  238. // 中序遍历
  239. void BST::inOrder()
  240. {
  241. inOrder(root);
  242. }
  243. int main(void)
  244. {
  245. int t;
  246. cin >> t;
  247. while (t--)
  248. {
  249. // 构建二叉平衡树,并在插入元素时做平衡处理
  250. int n, elem;
  251. cin >> n;
  252. BST tree;
  253. int n1 = n;
  254. while (n--)
  255. {
  256. cin >> elem;
  257. tree.insertAVL(elem);
  258. }
  259. tree.inOrder();
  260. for (int i = 0; i < n1; i++)
  261. {
  262. cout << a[i] << ":" << b[i];
  263. if (i != n1 - 1)
  264. cout << " ";
  265. if(t)
  266. cout << endl;
  267. z = 0;
  268. }
  269. return 0;
  270. }

C. 二叉平衡树练习

题目描述

对二叉平衡树进行四种操作:

  1. 1 D K 表示插入一个新数据,数据为D用于输出,关键值为K用于排序
  2. 2 输出当前树中最大关键值所带的数据,并删除该数据,如果没有这个关键值,则输出0
  3. 3 输出当前树中最小关键值所带的数据,并删除该数据,如果没有这个关键值,则输出0
  4. 4 K 输出关键值为 K 的数据,并删除该数据,如果没有这个关键值,则输出0

要求必须实现平衡树,不可以使用各类库函数

AVL代码模板参考:

  1. #include<stdio.h>
  2. const int maxn = 1e5 + 10;
  3. struct Node
  4. {
  5. int key; // 关键值
  6. int data; // 携带的数据
  7. int left; // 左子树地址(数组下标)
  8. int right; // 右子树地址(数组下标)
  9. int height; // 当前结点为根的子树高度
  10. void Init(){data = key = left = right = height = -1;}
  11. void Init(int k_, int d_=0){Init(); key = k_; data = d_;}
  12. Node(){Init();}
  13. Node(int k_, int d_=0){Init(k_, d_);}
  14. };
  15. Node tr[maxn];
  16. int root, tp; // root标记根节点位置,tp全局结点分配下标
  17. inline int UpdateHeight(int now)
  18. {
  19. // 更新 tr[now] 结点的子树高度,即tr[now].height的值
  20. }
  21. inline int HeightDiff(int now)
  22. {
  23. // 计算 tr[now] 结点的平衡因子
  24. }
  25. int LL(int an)
  26. {
  27. }
  28. int RR(int an)
  29. {
  30. }
  31. int LR(int an)
  32. {
  33. }
  34. int RL(int an)
  35. {
  36. }
  37. void Insert(int &now, int key, int data=0)
  38. {
  39. if(now == -1)
  40. {
  41. // 传入指针为空,新建结点保存数据
  42. now = ++ tp;
  43. tr[now].Init(key, data);
  44. }
  45. // 判断插入哪个子树,插入数据,判断平衡因子,做正确旋转,更新高度
  46. }
  47. void Delete(int &now, int key)
  48. {
  49. if(now == -1) return;
  50. else if(key < tr[now].key) Delete(tr[now].left, key);
  51. else if(key > tr[now].key) Delete(tr[now].right, key);
  52. else
  53. {
  54. // 删除当前结点
  55. }
  56. // 处理树平衡
  57. }
  58. int main()
  59. {
  60. int n, op, key, data;
  61. while(scanf("%d", &n) != EOF)
  62. {
  63. for(root = tp = -1; n --; ) // 初始化根结点和“内存指针”
  64. {
  65. scanf("%d", &op);
  66. if(op == 1)
  67. {
  68. }
  69. else if(op == 2)
  70. {
  71. }
  72. else if(op == 3)
  73. {
  74. }
  75. else
  76. {
  77. }
  78. }
  79. return 0;
  80. }

输入

每组数据第一行n表示有n个操作

接下来n行操作内容

8
2
1 20 14
1 30 3
2
1 10 99
3
2
2

输出

按操作规则输出对应内容

0
20
30
10
0

  1. #include<iostream>
  2. #include<cstdio>
  3. #include <vector>
  4. using namespace std;
  5. int Max(int a, int b)
  6. {
  7. if (a<b)
  8. {
  9. return b;
  10. }
  11. else
  12. {
  13. return a;
  14. }
  15. }
  16. const int maxn = 1e5 + 10;
  17. struct Node
  18. {
  19. int key; // 关键值
  20. int data; // 携带的数据
  21. int left; // 左子树地址(数组下标)
  22. int right; // 右子树地址(数组下标)
  23. int height; // 当前结点为根的子树高度
  24. void Init() { data = key = left = right = height = -1; }
  25. void Init(int k_, int d_ = 0) { Init(); key = k_; data = d_; }
  26. Node() { Init(); }
  27. Node(int k_, int d_ = 0) { Init(k_, d_); }
  28. };
  29. Node tr[maxn];
  30. int root, tp; // root标记根节点位置,tp全局结点分配下标
  31. inline int UpdateHeight(int now)
  32. {
  33. // 更新 tr[now] 结点的子树高度,即tr[now].height的值
  34. return tr[now].height = Max(tr[tr[now].left].height, tr[tr[now].right].height) + 1;
  35. }
  36. inline int HeightDiff(int now)
  37. {
  38. // 计算 tr[now] 结点的平衡因子
  39. return tr[tr[now].left].height - tr[tr[now].right].height;
  40. }
  41. int LL(int an)
  42. {
  43. int bn = tr[an].left;
  44. tr[an].left = tr[bn].right;
  45. tr[bn].right = an;
  46. UpdateHeight(an);
  47. UpdateHeight(bn);
  48. return bn;
  49. }
  50. int RR(int an)
  51. {
  52. int bn = tr[an].right;
  53. tr[an].right = tr[bn].left;
  54. tr[bn].left = an;
  55. UpdateHeight(an);
  56. UpdateHeight(bn);
  57. return bn;
  58. }
  59. int LR(int an)
  60. {
  61. tr[an].left = RR(tr[an].left);
  62. return LL(an);
  63. }
  64. int RL(int an)
  65. {
  66. tr[an].right = LL(tr[an].right);
  67. return RR(an);
  68. }
  69. void Insert(int& now, int key, int data = 0)
  70. {
  71. if (now == -1)
  72. {
  73. // 传入指针为空,新建结点保存数据
  74. now = ++tp;
  75. tr[now].Init(key, data);
  76. }
  77. // 判断插入哪个子树,插入数据,判断平衡因子,做正确旋转,更新高度
  78. else if (key < tr[now].key)
  79. {
  80. Insert(tr[now].left, key, data);
  81. if (HeightDiff(now) == 2)
  82. {
  83. if (key < tr[tr[now].left].key) now = LL(now);
  84. else now = LR(now);
  85. }
  86. }
  87. else if (key > tr[now].key)
  88. {
  89. Insert(tr[now].right, key, data);
  90. if (HeightDiff(now) == -2)
  91. {
  92. if (key > tr[tr[now].right].key) now = RR(now);
  93. else now = RL(now);
  94. }
  95. }
  96. UpdateHeight(now);
  97. }
  98. int FindMax(int now)
  99. {
  100. if (tr[now].right == 0)return -1;
  101. while (tr[now].right != -1) now = tr[now].right;
  102. return now;
  103. }
  104. int FindMin(int now)
  105. {
  106. if (tr[now].left == 0)return -1;
  107. while (tr[now].left != -1) now = tr[now].left;
  108. return now;
  109. }
  110. void Delete(int& now, int key)
  111. {
  112. if (now == -1) return;
  113. else if (key < tr[now].key) Delete(tr[now].left, key);
  114. else if (key > tr[now].key) Delete(tr[now].right, key);
  115. else
  116. {
  117. // 删除当前结点
  118. if (tr[now].left == -1 && tr[now].right == -1)
  119. {
  120. now = -1;
  121. return;
  122. }
  123. else if (tr[now].left != -1 && tr[now].right == -1)
  124. {
  125. now = tr[now].left;
  126. return;
  127. }
  128. else if (tr[now].left == -1 && tr[now].right != -1)
  129. {
  130. now = tr[now].right;
  131. return;
  132. }
  133. else
  134. {
  135. int maxLeftIndex = FindMax(tr[now].left);
  136. swap(tr[now].key, tr[maxLeftIndex].key);
  137. swap(tr[now].data, tr[maxLeftIndex].data);
  138. Delete(tr[now].left, tr[maxLeftIndex].key);
  139. if (HeightDiff(now) == 2)
  140. {
  141. if (HeightDiff(tr[now].left) >= 0) now = LL(now);
  142. else now = LR(now);
  143. }
  144. UpdateHeight(now);
  145. }
  146. }
  147. // 处理树平衡
  148. if (HeightDiff(now) == 2)
  149. {
  150. if (HeightDiff(tr[now].left) >= 0) now = LL(now);
  151. else now = LR(now);
  152. }
  153. else if (HeightDiff(now) == -2)
  154. {
  155. if (HeightDiff(tr[now].right) <= 0) now = RR(now);
  156. else now = RL(now);
  157. }
  158. UpdateHeight(now);
  159. }
  160. void InorderTraversal(int now, vector<int>& res)
  161. {
  162. if (now == -1) return;
  163. InorderTraversal(tr[now].left, res);
  164. res.push_back(tr[now].key);
  165. InorderTraversal(tr[now].right, res);
  166. }
  167. int main()
  168. {
  169. int n, op, key, data;
  170. while (scanf("%d", &n) != EOF)
  171. {
  172. for (root = tp = -1; n--; ) // 初始化根结点和“内存指针”
  173. {
  174. scanf("%d", &op);
  175. if (op == 1)
  176. {
  177. scanf("%d%d", &data, &key);
  178. Insert(root, key, data);
  179. }
  180. else if (op == 2)
  181. {
  182. int maxNodeIndex = FindMax(root);
  183. if (maxNodeIndex == -1 || tr[maxNodeIndex].data < 0)
  184. {
  185. printf("0\n");
  186. }
  187. else
  188. {
  189. printf("%d\n", tr[maxNodeIndex].data);
  190. Delete(root, tr[maxNodeIndex].key);
  191. }
  192. }
  193. else if (op == 3)
  194. {
  195. int minNodeIndex = FindMin(root);
  196. if (minNodeIndex == -1 || tr[minNodeIndex].data < 0)
  197. {
  198. printf("0\n");
  199. }
  200. else
  201. {
  202. printf("%d\n", tr[minNodeIndex].data);
  203. Delete(root, tr[minNodeIndex].key);
  204. }
  205. }
  206. else
  207. {
  208. scanf("%d", &key);
  209. int nodeIndex = root;
  210. while (nodeIndex != -1 && tr[nodeIndex].key != key)
  211. {
  212. if (tr[nodeIndex].key < key)
  213. {
  214. nodeIndex = tr[nodeIndex].right;
  215. }
  216. else
  217. {
  218. nodeIndex = tr[nodeIndex].left;
  219. }
  220. }
  221. if (nodeIndex == -1 || tr[nodeIndex].data < 0)
  222. {
  223. printf("0\n");
  224. }
  225. else
  226. {
  227. printf("%d\n", tr[nodeIndex].data);
  228. Delete(root, key);
  229. }
  230. }
  231. }
  232. }
  233. return 0;
  234. }

D. 平衡树上的第k小

题目描述

二种操作:

  1. 1 Key 表示插入一个新数据Key
  2. 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

  1. #include <iostream>
  2. using namespace std;
  3. struct TreeNode {
  4. int key, height, size;
  5. TreeNode *left, *right;
  6. TreeNode(int k) : key(k), height(1), size(1), left(nullptr), right(nullptr) {}
  7. };
  8. int height(TreeNode *node) {
  9. return node ? node->height : 0;
  10. }
  11. int balanceFactor(TreeNode *node) {
  12. return height(node->right) - height(node->left);
  13. }
  14. void updateHeightAndSize(TreeNode *node) {
  15. node->height = max(height(node->left), height(node->right)) + 1;
  16. node->size = (node->left ? node->left->size : 0) + (node->right ? node->right->size : 0) + 1;
  17. }
  18. void rotateRight(TreeNode *&node) {
  19. TreeNode *left = node->left;
  20. node->left = left->right;
  21. left->right = node;
  22. updateHeightAndSize(node);
  23. updateHeightAndSize(left);
  24. node = left;
  25. }
  26. void rotateLeft(TreeNode *&node) {
  27. TreeNode *right = node->right;
  28. node->right = right->left;
  29. right->left = node;
  30. updateHeightAndSize(node);
  31. updateHeightAndSize(right);
  32. node = right;
  33. }
  34. void balance(TreeNode *&node) {
  35. if (balanceFactor(node) == 2) {
  36. if (balanceFactor(node->right) < 0) {
  37. rotateRight(node->right);
  38. }
  39. rotateLeft(node);
  40. } else if (balanceFactor(node) == -2) {
  41. if (balanceFactor(node->left) > 0) {
  42. rotateLeft(node->left);
  43. }
  44. rotateRight(node);
  45. }
  46. updateHeightAndSize(node);
  47. }
  48. void insert(TreeNode *&node, int key) {
  49. if (!node) {
  50. node = new TreeNode(key);
  51. } else if (key < node->key) {
  52. insert(node->left, key);
  53. } else if (key > node->key) {
  54. insert(node->right, key);
  55. }
  56. balance(node);
  57. }
  58. int getKth(TreeNode *&node, int k) {
  59. int r = (node->left ? node->left->size : 0) + 1;
  60. if (k == r) {
  61. int res = node->key;
  62. if (!node->left && !node->right) {
  63. delete node;
  64. node = nullptr;
  65. } else if (node->left && !node->right) {
  66. TreeNode *tmp = node;
  67. node = node->left;
  68. delete tmp;
  69. } else if (!node->left && node->right) {
  70. TreeNode *tmp = node;
  71. node = node->right;
  72. delete tmp;
  73. } else {
  74. TreeNode *p = node->right;
  75. while (p->left) {
  76. p = p->left;
  77. }
  78. node->key = p->key;
  79. getKth(node->right, 1);
  80. }
  81. return res;
  82. } else if (k < r) {
  83. return getKth(node->left, k);
  84. } else {
  85. return getKth(node->right, k - r);
  86. }
  87. }
  88. int main() {
  89. int n;
  90. cin >> n;
  91. TreeNode *root = nullptr;
  92. for (int i = 0; i < n; i++) {
  93. int op, k;
  94. cin >> op >> k;
  95. if (op == 1) { // 插入操作
  96. insert(root, k);
  97. } else if (op == 2) { // 查找并删除第 k 小的元素
  98. if (root && root->size >= k) {
  99. cout << getKth(root, k) << endl;
  100. } else {
  101. cout << -1 << endl;
  102. }
  103. }
  104. }
  105. return 0;
  106. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/766294
推荐阅读
相关标签
  

闽ICP备14008679号