• M的编程备忘录之C++——搜索二叉树


    目录

    1、搜索二叉树概念

    2、搜索二叉树操作

    2.1、搜索二叉树的搜索

    2.2、二叉搜索树的插入

    2.3、二叉搜索树的删除

    3、二叉搜索树实现


    1、搜索二叉树概念

            二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
                    若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
                    若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
                    它的左右子树也分别为二叉搜索树

    2、搜索二叉树操作

    2.1、搜索二叉树的搜索

            1、从根开始比较,查找,比根大则往右边走查找,比根小则往左边走查找。
            2、最多查找高度次,走到到空,还没找到,这个值不存在。

    2.2、二叉搜索树的插入

            插入的具体过程如下:         
                    1、树为空,则直接新增节点,赋值给root指针
                    2、树不空,按二叉搜索树性质查找插入位置,插入新节点

    2.3、二叉搜索树的删除

            首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
            a. 要删除的结点无孩子结点
            b. 要删除的结点只有左孩子结点,删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点--直接删除
            c. 要删除的结点只有右孩子结点,删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点--直接删除
            d. 要删除的结点有左、右孩子结点,在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题--替换法删除

    3、二叉搜索树实现

    1. template<class K, class V >
    2. struct BSTreeNode
    3. {
    4. BSTreeNode* _left;
    5. BSTreeNode* _right;
    6. K _key;
    7. V _vaule;
    8. BSTreeNode(const K& key, const V& vaule = key)
    9. :_left(nullptr)
    10. ,_right(nullptr)
    11. ,_key(key)
    12. ,_vaule(vaule)
    13. {}
    14. };
    15. template<class K, class V >
    16. class BSTree
    17. {
    18. typedef BSTreeNode Node;
    19. public:
    20. BSTree() = default;
    21. BSTree(const BSTree& t)
    22. {
    23. _root = CopyTree(t._root);
    24. }
    25. BSTree& operator=(BSTree t)
    26. {
    27. swap(_root, t._root);
    28. return *this;
    29. }
    30. ~BSTree()
    31. {
    32. DestoryTree(_root);
    33. _root == nullptr;
    34. }
    35. //迭代实现
    36. bool Insert(const K& key, const V& value = key)
    37. {
    38. if (_root == nullptr)
    39. {
    40. _root = new Node(key, value);
    41. return true;
    42. }
    43. Node* parent = nullptr;
    44. Node* cur = _root;
    45. while (cur)
    46. {
    47. if (cur->_key > key)
    48. {
    49. parent = cur;
    50. cur = cur->_left;
    51. }
    52. else if (cur->_key < key)
    53. {
    54. parent = cur;
    55. cur = cur->_right;
    56. }
    57. else
    58. {
    59. return false;
    60. }
    61. }
    62. cur = new Node(key, value);
    63. if (parent->_key > key)
    64. {
    65. parent->_left = cur;
    66. }
    67. else
    68. {
    69. parent->_right = cur;
    70. }
    71. return true;
    72. }
    73. Node* Find(const K& key)
    74. {
    75. Node* cur = _root;
    76. while (cur)
    77. {
    78. if (cur->_key < key)
    79. {
    80. cur = cur->_right;
    81. }
    82. else if (cur->_key > key)
    83. {
    84. cur = cur->_left;
    85. }
    86. else
    87. {
    88. return cur;
    89. }
    90. }
    91. return nullptr;
    92. }
    93. bool Erase(const K& key)
    94. {
    95. Node* parent = nullptr;
    96. Node* cur = _root;
    97. while (cur)
    98. {
    99. if (cur->_key > key)
    100. {
    101. parent = cur;
    102. cur = cur->_left;
    103. }
    104. else if (cur->_key < key)
    105. {
    106. parent = cur;
    107. cur = cur->_right;
    108. }
    109. else
    110. {
    111. if (cur->_left == nullptr)
    112. {
    113. if (cur == _root)
    114. {
    115. _root = cur->_right;
    116. }
    117. else
    118. {
    119. if (cur == parent->_left)
    120. {
    121. parent->_left = cur->_right;
    122. }
    123. else
    124. {
    125. parent->_right = cur->_right;
    126. }
    127. }
    128. delete cur;
    129. }
    130. else if (cur->_right == nullptr)
    131. {
    132. if (cur == _root)
    133. {
    134. _root = cur->_left;
    135. }
    136. else
    137. {
    138. if (cur == parent->_left)
    139. {
    140. parent->_left = cur->_left;
    141. }
    142. else
    143. {
    144. parent->_right = cur->_left;
    145. }
    146. }
    147. delete cur;
    148. }
    149. else
    150. {
    151. Node* minparent = cur;
    152. Node* minRight = cur->_right;
    153. while (minRight->_left)
    154. {
    155. minparent = minRight;
    156. minRight = minRight->_left;
    157. }
    158. swap(cur->_key, minRight->_key);
    159. if (minparent->_left == minRight)
    160. {
    161. minparent->_left = minRight->_right;
    162. }
    163. else
    164. {
    165. minparent->_right = minRight->_right;
    166. }
    167. delete minRight;
    168. }
    169. return true;
    170. }
    171. }
    172. return false;
    173. }
    174. void InOrder()
    175. {
    176. _InOrder(_root);
    177. }
    178. //递归实现
    179. bool FindR(const K& key, const V& value)
    180. {
    181. return _FindR(_root, key, value);
    182. }
    183. bool EraseR(const K& key)
    184. {
    185. return _EraseR(_root, key);
    186. }
    187. bool InsertR(const K& key, const V& value)
    188. {
    189. return _InsertR(_root, key, value);
    190. }
    191. private:
    192. bool _FindR(Node* root, const K& key, const V& value)
    193. {
    194. if (root == nullptr)
    195. {
    196. return false;
    197. }
    198. if (root->_key > key)
    199. {
    200. return _FindR(_root, key, value);
    201. }
    202. else if (root->_key < key)
    203. {
    204. return _FindR(_root, key, value);
    205. }
    206. else
    207. {
    208. return true;
    209. }
    210. }
    211. bool _EraseR(Node*& root, const K& key)
    212. {
    213. if (root == nullptr)
    214. {
    215. return false;
    216. }
    217. if (root->_key > key)
    218. {
    219. return _EraseR(root->_left, key);
    220. }
    221. else if (root->_key < key)
    222. {
    223. return _EraseR(root->_right, key);
    224. }
    225. else
    226. {
    227. Node* del = root;
    228. if (root->_left == nullptr)
    229. {
    230. root = root->_right;
    231. }
    232. else if (root->_right == nullptr)
    233. {
    234. root = root->_left;
    235. }
    236. else
    237. {
    238. Node* minRight = root->_right;
    239. while (minRight->_left)
    240. {
    241. minRight = minRight->_left;
    242. }
    243. swap(root->_key, minRight->_key);
    244. return _EraseR(root->_right, key);
    245. }
    246. delete del;
    247. return true;
    248. }
    249. }
    250. bool _InsertR(Node*& root,const K& key, const V& value)
    251. {
    252. if (root == nullptr)
    253. {
    254. root = new Node(key, value);
    255. return true;
    256. }
    257. if (root->_key > key)
    258. {
    259. return _InsertR(root->_left, key, value);
    260. }
    261. else if (root->_key < key)
    262. {
    263. return _InsertR(root->_right, key, value);
    264. }
    265. else
    266. {
    267. return false;
    268. }
    269. }
    270. void _InOrder(Node* root)
    271. {
    272. if (root == nullptr)
    273. {
    274. return;
    275. }
    276. _InOrder(root->_left);
    277. cout << root->_vaule << " ";
    278. _InOrder(root->_right);
    279. }
    280. void DestoryTree(Node* root)
    281. {
    282. if (root == nullptr)
    283. {
    284. return;
    285. }
    286. DestoryTree(root->_left);
    287. DestoryTree(root->_right);
    288. delete root;
    289. }
    290. Node* CopyTree(Node* root)
    291. {
    292. if (root == nullptr)
    293. {
    294. return nullptr;
    295. }
    296. Node* copyNode = new Node(root->_key, root->_vaule);
    297. copyNode->_left = CopyTree(root->_left);
    298. copyNode->_right = CopyTree(root->_right);
    299. return copyNode;
    300. }
    301. private:
    302. Node* _root = nullptr;
    303. };

  • 相关阅读:
    【历史上的今天】6 月 28 日:马斯克诞生;微软推出 Office 365;蔡氏电路的发明者出生
    elementui表单的验证问题
    Spring Cloud Eureka:服务注册与发现
    docker基本使用总结
    循环掌控:深入理解C语言循环结构,高效实现重复性任务
    用DIV+CSS技术设计的公益主题网站——防止电信诈骗(web前端网页制作课作业)
    数据分析中的pandas文章目录汇总
    Docker入门-上篇
    面试官:Java中缓冲流真的性能很好吗?我看未必
    vue中使用echarts实现省市地图绘制,根据数据显示不同区域颜色,点击省市切换,根据经纬度打点
  • 原文地址:https://blog.csdn.net/HyperMyteki/article/details/126377988