[关闭]
@CrazyHenry 2018-03-06T17:47:43.000000Z 字数 4387 阅读 965

0.x 13.二叉搜索树

dddd数据结构课本


  1. #include <iostream>
  2. #include <queue>
  3. #include <cassert>
  4. using namespace std;
  5. // 二分搜索树
  6. template <typename Key, typename Value>
  7. class BST{
  8. private:
  9. // 树中的节点为私有的结构体, 外界不需要了解二分搜索树节点的具体实现
  10. struct Node{
  11. Key key;
  12. Value value;
  13. Node *left = nullptr;
  14. Node *right = nullptr;
  15. Node(Key key, Value value): key(key), value(value){}
  16. //拷贝构造,在remove函数里使用
  17. Node(Node *node): key(node->key),value(node->value),left(node->left),right(node->right){}
  18. };
  19. Node *root = nullptr; // 根节点
  20. int count = 0; // 树中的节点个数
  21. public:
  22. // 构造函数, 默认构造一棵空二分搜索树
  23. BST(){}
  24. // 析构函数, 释放二分搜索树的所有空间
  25. ~BST(){
  26. destroy( root );
  27. }
  28. // 返回二分搜索树的节点个数
  29. int size(){
  30. return count;
  31. }
  32. // 返回二分搜索树是否为空
  33. bool isEmpty(){
  34. return count == 0;
  35. }
  36. // 向二分搜索树中插入一个新的(key, value)数据对
  37. void insert(Key key, Value value){
  38. root = insert(root, key, value);
  39. }
  40. // 查看二分搜索树中是否存在键key
  41. bool contain(Key key){
  42. return contain(root, key);
  43. }
  44. // 在二分搜索树中搜索键key所对应的值。如果这个值不存在, 则返回nullptr
  45. Value* search(Key key){
  46. return search( root , key );
  47. }
  48. // 二分搜索树的前序遍历
  49. void preOrder(){
  50. preOrder(root);
  51. }
  52. // 二分搜索树的中序遍历
  53. void inOrder(){
  54. inOrder(root);
  55. }
  56. // 二分搜索树的后序遍历
  57. void postOrder(){
  58. postOrder(root);
  59. }
  60. // 二分搜索树的层序遍历
  61. void levelOrder(){
  62. queue<Node*> q;
  63. q.push(root);
  64. while( !q.empty() ){
  65. Node *node = q.front();
  66. q.pop();
  67. cout<<node->key<<endl;
  68. if( node->left )
  69. q.push( node->left );
  70. if( node->right )
  71. q.push( node->right );
  72. }
  73. }
  74. // 寻找二分搜索树的最小的键值
  75. Key minimum(){
  76. assert( count != 0 );
  77. Node* minNode = minimum( root );
  78. return minNode->key;
  79. }
  80. // 寻找二分搜索树的最大的键值
  81. Key maximum(){
  82. assert( count != 0 );
  83. Node* maxNode = maximum(root);
  84. return maxNode->key;
  85. }
  86. // 从二分搜索树中删除最小值所在节点
  87. void removeMin(){
  88. if( root )
  89. root = removeMin( root );
  90. }
  91. // 从二分搜索树中删除最大值所在节点
  92. void removeMax(){
  93. if( root )
  94. root = removeMax( root );
  95. }
  96. // 从二分搜索树中删除键值为key的节点
  97. void remove(Key key){
  98. root = remove(root, key);
  99. }
  100. private:
  101. // 向以node为根的二分搜索树中, 插入节点(key, value), 使用递归算法
  102. // 返回插入新节点后的二分搜索树的根
  103. Node* insert(Node *node, Key key, Value value){
  104. if( node == nullptr ){
  105. ++count;
  106. return new Node(key, value);
  107. }
  108. if( key == node->key )
  109. node->value = value;
  110. else if( key < node->key )
  111. node->left = insert( node->left , key, value);
  112. else // key > node->key
  113. node->right = insert( node->right, key, value);
  114. return node;
  115. }
  116. // 查看以node为根的二分搜索树中是否包含键值为key的节点, 使用递归算法
  117. bool contain(Node* node, Key key){
  118. if( node == nullptr )
  119. return false;
  120. if( key == node->key )
  121. return true;
  122. else if( key < node->key )
  123. return contain( node->left , key );
  124. else // key > node->key
  125. return contain( node->right , key );
  126. }
  127. // 在以node为根的二分搜索树中查找key所对应的value, 递归算法
  128. // 若value不存在, 则返回NULL
  129. Value* search(Node* node, Key key){
  130. if( node == nullptr )
  131. return nullptr;
  132. if( key == node->key )
  133. return &(node->value);
  134. else if( key < node->key )
  135. return search( node->left , key );
  136. else // key > node->key
  137. return search( node->right, key );
  138. }
  139. // 对以node为根的二分搜索树进行前序遍历, 递归算法
  140. void preOrder(Node* node){
  141. if( node != nullptr ){
  142. cout<<node->key<<endl;
  143. preOrder(node->left);
  144. preOrder(node->right);
  145. }
  146. }
  147. // 对以node为根的二分搜索树进行中序遍历, 递归算法
  148. void inOrder(Node* node){
  149. if( node != nullptr ){
  150. inOrder(node->left);
  151. cout<<node->key<<endl;
  152. inOrder(node->right);
  153. }
  154. }
  155. // 对以node为根的二分搜索树进行后序遍历, 递归算法
  156. void postOrder(Node* node){
  157. if( node != nullptr ){
  158. postOrder(node->left);
  159. postOrder(node->right);
  160. cout<<node->key<<endl;
  161. }
  162. }
  163. // 释放以node为根的二分搜索树的所有节点
  164. // 采用后续遍历的递归算法
  165. void destroy(Node* node){
  166. if( node != nullptr ){
  167. destroy( node->left );
  168. destroy( node->right );
  169. delete node;
  170. --count;
  171. }
  172. }
  173. // 返回以node为根的二分搜索树的最小键值所在的节点, 递归算法
  174. Node* minimum(Node* node){
  175. if( node->left == nullptr )
  176. return node;
  177. return minimum(node->left);
  178. }
  179. // 返回以node为根的二分搜索树的最大键值所在的节点, 递归算法
  180. Node* maximum(Node* node){
  181. if( node->right == nullptr )
  182. return node;
  183. return maximum(node->right);
  184. }
  185. // 删除掉以node为根的二分搜索树中的最小节点, 递归算法
  186. // 返回删除节点后新的二分搜索树的根
  187. Node* removeMin(Node* node){
  188. if( node->left == nullptr ){
  189. Node* rightNode = node->right;
  190. delete node;
  191. --count;
  192. return rightNode;
  193. }
  194. node->left = removeMin(node->left);
  195. return node;
  196. }
  197. // 删除掉以node为根的二分搜索树中的最大节点, 递归算法
  198. // 返回删除节点后新的二分搜索树的根
  199. Node* removeMax(Node* node){
  200. if( node->right == nullptr ){
  201. Node* leftNode = node->left;
  202. delete node;
  203. --count;
  204. return leftNode;
  205. }
  206. node->right = removeMax(node->right);
  207. return node;
  208. }
  209. // 删除掉以node为根的二分搜索树中键值为key的节点, 递归算法
  210. // 返回删除节点后新的二分搜索树的根
  211. Node* remove(Node* node, Key key){
  212. if( node == nullptr )
  213. return nullptr;
  214. if( key < node->key ){
  215. node->left = remove( node->left , key );
  216. return node;
  217. }
  218. else if( key > node->key ){
  219. node->right = remove( node->right, key );
  220. return node;
  221. }
  222. else{ // key == node->key
  223. // 待删除节点左子树为空的情况
  224. if( node->left == nullptr ){
  225. Node *rightNode = node->right;
  226. delete node;
  227. --count;
  228. return rightNode;
  229. }
  230. // 待删除节点右子树为空的情况
  231. if( node->right == nullptr ){
  232. Node *leftNode = node->left;
  233. delete node;
  234. --count;
  235. return leftNode;
  236. }
  237. // 待删除节点左右子树均不为空的情况
  238. // 找到比待删除节点大的最小节点, 即待删除节点右子树的最小节点
  239. // 用这个节点顶替待删除节点的位置
  240. Node *successor = new Node(minimum(node->right));
  241. ++count;
  242. successor->right = removeMin(node->right);
  243. successor->left = node->left;
  244. delete node;
  245. --count;
  246. return successor;
  247. }
  248. }
  249. };
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注