当前位置:   article > 正文

C++实现二叉排序树的创建、中序遍历与删除操作_c++设计一个算法读入一串整数,然后构造二叉排序树,进行查找与删除

c++设计一个算法读入一串整数,然后构造二叉排序树,进行查找与删除

 BinTree.h

  1. #pragma once
  2. #include<iostream>
  3. #include<vector>
  4. using namespace std;
  5. /*
  6. 二叉排序树,对二叉排序树进行中序遍历,可以得到一个递增的有序序列
  7. */
  8. template<class T> class BinNode
  9. {
  10. public:
  11. T key;
  12. BinNode* lchild, * rchild;
  13. };
  14. template<class T> class BinTree
  15. {
  16. public:
  17. BinTree();//默认构造
  18. BinTree(T* arr, int len);//数组构造
  19. BinTree(vector<T> vec);//容器构造
  20. bool Insert(T& key);//插入节点
  21. void InOrder();//中序遍历外部接口
  22. bool Search(T key);//查找结点
  23. bool Delete(T& key);//删除结点
  24. bool isEmpty();//判断树是否为空树
  25. private:
  26. BinNode<T>* TNode;
  27. void _InOrder(BinNode<T>* T);//中序遍历内部实现
  28. void _visit(BinNode<T>* T);//访问结点内部实现
  29. BinNode<T>* _Search(BinNode<T>* t, T key);//查找结点内部实现
  30. bool _isLeaf(BinNode<T>* t);//判断一个结点是不是叶子节点
  31. bool _isNodeWithTwoChild(BinNode<T>* t);//判断一个结点是否有左右两棵子树
  32. BinNode<T>* _NodeMin(BinNode<T>* t, BinNode<T>*& parent);//找到当前节点为根的树中的最小值
  33. BinNode<T>* _Delete(BinNode<T>*& t);//删除根结点 并返回新的根节点,
  34. //针对只有一颗左或右子树的结点,删除结点时用到
  35. };
  36. template<class T> BinTree<T>::BinTree()//默认构造
  37. {
  38. TNode = NULL;
  39. }
  40. template<class T> BinTree<T>::BinTree(T* arr, int len)//数组构造
  41. {
  42. TNode = NULL;
  43. for (int i = 0; i < len; ++i)
  44. {
  45. Insert(*(arr + i));
  46. }
  47. }
  48. template<class T> BinTree<T>::BinTree(vector<T> vec)//容器构造
  49. {
  50. TNode = NULL;
  51. for (int i = 0; i < vec.size(); ++i)
  52. {
  53. Insert(vec[i]);
  54. }
  55. }
  56. template<class T> bool BinTree<T>::Insert(T& key)//插入节点
  57. {
  58. BinNode<T>* p = new BinNode<T>();//临时结点
  59. p->key = key;
  60. p->lchild = p->rchild = NULL;
  61. BinNode<T>* parent = new BinNode<T>();
  62. parent = NULL;
  63. if (TNode == NULL)//如果原树为空,则创建新树,插入的结点作为根节点
  64. {
  65. TNode = p;
  66. return true;
  67. }
  68. else
  69. {
  70. BinNode<T>* cur = TNode;
  71. while (cur)//插入的结点肯定是叶子结点,寻找叶子节点(parent)
  72. {
  73. if (cur->key == key)
  74. return false;
  75. else if (cur->key > key)
  76. {
  77. parent = cur;
  78. cur = cur->lchild;
  79. }
  80. else if (cur->key < key)
  81. {
  82. parent = cur;
  83. cur = cur->rchild;
  84. }
  85. }
  86. if (p->key < parent->key)
  87. {
  88. parent->lchild = p;
  89. return true;
  90. }
  91. else
  92. {
  93. parent->rchild = p;
  94. return true;
  95. }
  96. }
  97. }
  98. template<class T> void BinTree<T>::_visit(BinNode<T>* T)//访问结点
  99. {
  100. cout << T->key << endl;
  101. }
  102. template<class T> void BinTree<T>::_InOrder(BinNode<T>* T)//递归中序遍历内部函数
  103. {
  104. if (T != NULL)
  105. {
  106. _InOrder(T->lchild);
  107. _visit(T);
  108. _InOrder(T->rchild);
  109. }
  110. }
  111. template<class T> void BinTree<T>::InOrder()//中序遍历外部接口
  112. {
  113. _InOrder(TNode);
  114. }
  115. template<class T> BinNode<T>* BinTree<T>::_Search(BinNode<T>* t, T key)//递归查找结点内部函数
  116. {
  117. if (t == NULL)
  118. return NULL;
  119. else
  120. {
  121. if (t->key == key)
  122. return t;
  123. else if (t->key > key)
  124. {
  125. return _Search(t->lchild, key);
  126. }
  127. else if (t->key < key)
  128. {
  129. return _Search(t->rchild, key);
  130. }
  131. }
  132. }
  133. template<class T> bool BinTree<T>::Search(T key)//查找结点外部接口
  134. {
  135. return _Search(TNode, key) == NULL ? false : true;;
  136. }
  137. template<class T> bool BinTree<T>::isEmpty()//判断树是否为空
  138. {
  139. return TNode == NULL;
  140. }
  141. template<class T> bool BinTree<T>::_isLeaf(BinNode<T>* t)//判断一个结点是否是叶子结点
  142. {
  143. if (!isEmpty())
  144. {
  145. if (t->lchild == NULL && t->rchild == NULL)
  146. return true;
  147. else
  148. return false;
  149. }
  150. else
  151. return false;
  152. }
  153. template<class T> bool BinTree<T>::_isNodeWithTwoChild(BinNode<T>* t)//判断一个结点是否有左右两棵子树
  154. {
  155. if (!isEmpty())
  156. {
  157. if (t->lchild != NULL && t->rchild != NULL)
  158. return true;
  159. else
  160. return false;
  161. }
  162. else
  163. return false;
  164. }
  165. //找到当前节点为根的树中的最小值
  166. template<class T> BinNode<T>* BinTree<T>::_NodeMin(BinNode<T>* t, BinNode<T>*& parent)
  167. {
  168. BinNode<T>* cur = t;
  169. while (cur->lchild != NULL)
  170. {
  171. parent = cur;
  172. cur = cur->lchild;
  173. }
  174. return cur;
  175. }
  176. template<class T> BinNode<T>* BinTree<T>::_Delete(BinNode<T>*& t)//一棵树仅有左孩子或者有孩子
  177. {
  178. if (t->lchild != NULL)
  179. return t->lchild;
  180. else
  181. return t->rchild;
  182. }
  183. //删除结点
  184. template<class T> bool BinTree<T>::Delete(T& key)
  185. {
  186. /*
  187. 先搜索找到目标结点z
  188. 删除节点分为三种情况:
  189. 1.若被删除节点z是叶节点,则直接删除,不会破坏二叉排序树的性质
  190. 2.若被删除节点z只有一棵左子树或右子树,则让z的子树替代z的位置
  191. 3.若被删除结点z有左右两棵子树,则令z的直接后继(或直接前驱)替代z,
  192. 然后从二叉排序树中删除这个直接后继(或直接前驱),这样就转换成了第一或第二种情况
  193. */
  194. if (isEmpty())
  195. {
  196. cout << "空树 无法删除" << endl;
  197. return false;
  198. }
  199. else
  200. {
  201. bool find = false;
  202. BinNode<T>* parent=TNode;
  203. //BinNode<T>* t = _Search(TNode, key,parent);
  204. BinNode<T>* cur = TNode;
  205. while (cur)
  206. {
  207. if (key < cur->key)
  208. {
  209. parent = cur;
  210. cur = cur->lchild;
  211. }
  212. else if (key > cur->key)
  213. {
  214. parent = cur;
  215. cur = cur->rchild;
  216. }
  217. else if (key == cur->key)
  218. {
  219. find = true;
  220. break;
  221. }
  222. }
  223. if (!find)
  224. {
  225. cout << "该结点未找到" << endl;
  226. return false;
  227. }
  228. if (_isLeaf(cur))
  229. {
  230. if (parent->lchild->key == key)
  231. parent->lchild = NULL;
  232. else
  233. parent->rchild = NULL;
  234. delete cur;
  235. return true;
  236. }
  237. else if (_isNodeWithTwoChild(cur))
  238. {//该结点右子树的最小值即为该节点的直接后继
  239. BinNode<T>* parent = cur;
  240. BinNode<T>* temp = _NodeMin(cur->rchild,parent);
  241. cur->key= temp->key;
  242. if (parent->rchild == temp)
  243. parent->rchild = _Delete(temp);
  244. else if (parent->lchild == temp)
  245. parent->lchild = _Delete(temp);
  246. delete temp;
  247. return true;
  248. }
  249. else
  250. {
  251. if (cur->lchild != NULL)
  252. {
  253. parent->lchild = _Delete(cur);
  254. delete cur;
  255. return true;
  256. }
  257. else
  258. {
  259. parent->rchild = _Delete(cur);
  260. delete cur;
  261. return true;
  262. }
  263. }
  264. }
  265. }

源.cpp

  1. #include <iostream>
  2. #include "BinTree.h"
  3. using namespace std;
  4. void test01()
  5. {
  6. int arr[] = { 19,13,11,8,50,26,21,30,66,60,70,63,61,65,71 };
  7. BinTree<int> T(arr,15);
  8. T.InOrder();
  9. cout << "-------" << endl;
  10. cout << T.Search(7) << endl;
  11. cout << T.Search(70) << endl;
  12. int a = 70;
  13. cout << "-------1" << endl;
  14. cout << T.Delete(a) << endl;
  15. cout << "-------------2" << endl;
  16. T.InOrder();
  17. }
  18. int main()
  19. {
  20. test01();
  21. return 0;
  22. }

 

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

闽ICP备14008679号