• 二叉搜索树


    目录

    二叉搜索树概念

    二叉搜索树的实现

    二叉搜索树的应用


    二叉搜索树概念

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


    二叉搜索树的实现

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

    其中带R的为递归实现


    二叉搜索树的应用

    1. K模型:K模型即只有key作为关键码,结构中只需要存储Key即可,关键码即为需要搜索到
    的值。
    比如:
    给一个单词word,判断该单词是否拼写正确,具体方式如下:
    以词库中所有单词集合中的每个单词作为key,构建一棵二叉搜索树在二叉搜索树中检索该单词是否存在,存在则拼写正确,不存在则拼写错误。

    小区车辆的门禁、宿舍门禁、教学楼门禁都是这种情景
    2. KV模型:每一个关键码key,都有与之对应的值Value,即的键值对。
    比如:
    英汉词典中英文与中文的对应关系,通过英文可以快速找到与其对应的中文,英文单词与其对应的中文就构成一种键值对;
    再比如统计单词次数,统计成功后,给定单词就可快速找到其出现的次数,单词与其出
    现次数就是就构成一种键值对
     


  • 相关阅读:
    java毕业设计大学生第二课堂Mybatis+系统+数据库+调试部署
    web端生成pdf,前端生成pdf导出并自定义页眉页脚
    卷积层数量过多的缺点,卷积积分的被积函数
    【OpenCV小练手】-仿造验证码去除干扰因子
    React Query:高效管理API请求与缓存
    【区块链技术与应用】(六)
    C++ sort函数自定义cmp函数中参数带&符号
    【教学类-06-06】20230905数字题目随便玩( 加减法、分合、比大小,纸张消耗)
    STM8应用笔记3.GPIO输出 (1)
    企业如何购买腾讯云服务器?(详细指南)
  • 原文地址:https://blog.csdn.net/m0_59793804/article/details/126021287