diff --git a/c-cpp/24_binarysearchtree/binary_search_tree.cpp b/c-cpp/24_binarysearchtree/binary_search_tree.cpp index 04fb1a2..4a43e38 100644 --- a/c-cpp/24_binarysearchtree/binary_search_tree.cpp +++ b/c-cpp/24_binarysearchtree/binary_search_tree.cpp @@ -1,50 +1,57 @@ +/* + * Filename: /home/zwk/code/data_structrue/c++/tree/binary_search_tree/main.cpp + * Path: /home/zwk/code/data_structrue/c++/tree/binary_search_tree + * Created Date: Wednesday, May 8th 2019, 11:04:48 pm + * Author: zwk + * + * refer to https://time.geekbang.org/column/article/68334 + */ + #include using namespace std; typedef int DataType; -struct tree_node +struct treeNode { - DataType data; - tree_node* left=NULL; - tree_node* right=NULL; + DataType data; + treeNode *left = nullptr; + treeNode *right = nullptr; }; -class binary_search_tree{ +class binarySearchTree +{ private: - tree_node* root; - int num; + treeNode *root; + int num; // tree node numbers public: - binary_search_tree() :num(0) - { - root = new tree_node; - root->left = NULL; - root->right = NULL; - } + binarySearchTree() : num(0) + { + root = new treeNode; + root->left = nullptr; + root->right = nullptr; + } - bool find(DataType it,tree_node* root) - { - if (NULL == root)return false; - if (it == root->data) { - return true; - } - else if (it > root->data) - { - return find(it, root->right); - } - else - { - return find(it, root->left); - } - } + bool find(DataType it, treeNode *root) + { + if (nullptr == root) + return false; + if (it == root->data) { + return true; + } else if (it > root->data) { + return find(it, root->right); + } else { + return find(it, root->left); + } + } - bool find_data(DataType it) - { - return find(it, root); - /* - tree_node* p = root; - while (p != NULL) + bool find_data(DataType it) + { + return find(it, root); + /* + treeNode* p = root; + while (p != nullptr) { if (it < p->data)p = p->left; else if (it>p->data)p = p->right; @@ -52,217 +59,233 @@ public: } return false; */ - } + } + DataType get_max() + { + if (nullptr == root) + return NULL; + treeNode *tmp = root; + while (tmp->right != nullptr) { + tmp = tmp->right; + } + return tmp->data; + } - void insert_data(DataType it) - { + DataType get_min() + { + if (nullptr == root) + return NULL; + treeNode *tmp = root; + while (tmp->left != nullptr) { + tmp = tmp->left; + } + return tmp->data; + } - if (0==num) - { - root->data = it; - num++; - return; - } - tree_node* p = root; - while (p != NULL) - { - if (it < p->data) - { - if (NULL == p->left) - { - p->left = new tree_node; - p->left->data = it; - num++; - return; - } - p = p->left; - } - else - { - if (NULL == p->right) - { - p->right = new tree_node; - p->right->data = it; - num++; - return; - } - p = p->right; - } - } - - } + void insert_data(DataType it) + // 利用二分查找的思想,借助树的结构使用递归 + { + if (0 == num) { + root->data = it; + num++; + return; + } + treeNode *p = root; + while (p != nullptr) { + if (it < p->data) { + if (nullptr == p->left) { + p->left = new treeNode; + p->left->data = it; + num++; + return; + } + p = p->left; + } else { + if (nullptr == p->right) { + p->right = new treeNode; + p->right->data = it; + num++; + return; + } + p = p->right; + } + } + } - void delet(DataType it) - { - if (NULL == root)return; - tree_node* p = root; - tree_node* pp = NULL;//pp¼pĸڵ - while (p != NULL&&p->data != it) - { - pp = p; - if (it > p->data)p = p->right; - else - p = p->left; - } - if (p == NULL)return;//ûҵ - //ɾĽڵӽڵ - if (p->left != NULL&&p->right != NULL) - { - tree_node* minP = p->right; - tree_node* minPP = p;//¼Pĸڵ - while (minP->left != NULL)//ѰСڵ - { - minPP = minP; - minP = minP->left; - } - p->data = minP->data;//minP滻p - //pҶڵϣʹҶڵ㷽ɾ - p = minP; - pp = minPP; - } + DataType get_prenode(DataType it) + { + if (nullptr == root) + return NULL; + if (it == root->data) + return NULL; + treeNode *p = root; + treeNode *pp = nullptr; + while (p != nullptr) { + if (p->data < it) { + pp = p; // label parent root + p = p->right; - //ɾڵҶڵǽһڵ - tree_node* child; - if (p->left != NULL) child = p->left; - else if (p->right != NULL) child = p->right; - else child = NULL; + } else if (p->data > it) { + pp = p; // label parent root + p = p->left; + } else { - if (NULL == pp) root = child;//ɾǸڵ - else if (p == pp->left)pp->left = child; - else pp->right = child; - } + break; + } + } + return ((nullptr == p) ? NULL : pp->data); + } - DataType get_max() - { - if (NULL == root)return NULL; - tree_node* tmp=root; - while (tmp->right != NULL) - { - tmp = tmp->right; - } - return tmp->data; - } - DataType get_min() - { - if (NULL == root)return NULL; - tree_node* tmp=root; - while (tmp->left != NULL) - { - tmp = tmp->left; - } - return tmp->data; - } + DataType get_postnode(DataType it) + { + if (nullptr == root) + return -1; + treeNode *p = root; + while (p != nullptr) { + if (p->data < it) { + p = p->right; + } else if (p->data > it) { + p = p->left; + } else { + break; + } + } + if (nullptr == p) { + return -1; + } else if (p->left != nullptr) { + return p->left->data; + } else if (p->right != nullptr) { + return p->right->data; + } else { + return NULL; + } + } - DataType get_prenode(DataType it) - { - if (NULL == root)return NULL; - if (it == root->data) return NULL; - tree_node* p=root; - tree_node* pp=NULL; - while ((p->data != it)&&(p!=NULL)) - { - pp = p; - if (p->data < it) - { - p=p->right; - } - else - { - p = p->left; - } - } - return ((NULL==p)?NULL:pp->data); - } + void mid_order(treeNode *rt) + { + if (nullptr == rt) + return; + mid_order(rt->left); + cout << rt->data << '\t'; + mid_order(rt->right); + } - DataType get_postnode(DataType it) - { - if (NULL == root)return -1; - tree_node* p = root; - while ((p->data != it) && (p != NULL)) - { - if (p->data < it) - { - p = p->left; - } - else - { - p = p->right; - } - } - if (NULL == p) - { - return -1; - } - else if (p->left!=NULL) - { - return p->left->data; - } - else if (p->right!=-NULL) - { - return p->right->data; - } - else - { - return NULL; - } - } + void order() + { + if (nullptr == root) + return; + return mid_order(root); + } - void mid_order(tree_node* rt) - { - if (NULL == rt)return; - mid_order(rt->left); - cout << rt->data; - mid_order(rt->right); - } - void order() - { - if (NULL == root)return; - return mid_order(root); - } + int get_high(treeNode *rt) + { + int lhigh = 0; + int rhigh = 0; + if (nullptr == rt) + return 0; + lhigh = get_high(rt->left); + rhigh = get_high(rt->right); + return ((lhigh > rhigh) ? (lhigh + 1) : (rhigh + 1)); + } - int get_high(tree_node* rt) - { - int lhigh = 0; - int rhigh = 0; - if (NULL == rt)return 0; - lhigh = get_high(rt->left); - rhigh = get_high(rt->right); - return ((lhigh > rhigh) ? (lhigh + 1) : (rhigh + 1)); - } + int high() + { + if (nullptr == root) + return 1; + return get_high(root); + } - int high() - { - if (NULL == root) return 1; - return get_high(root); - } + void delet(DataType it) + { + if (NULL == root) + return; + treeNode *p = root; + treeNode *pp = NULL; //pp记录的是p的父节点 + while (p != NULL && p->data != it) { + pp = p; + if (it > p->data) + p = p->right; + else + p = p->left; + } + if (p == NULL) + return; //没有找到 + //删除的节点有两个子节点 + if (p->left != NULL && p->right != NULL) { + treeNode *minP = p->right; + treeNode *minPP = p; //记录P的父节点 + while (minP->left != NULL) //寻找右子树最小节点 + { + minPP = minP; + minP = minP->left; + } + // 注意这里,非常巧妙的办法。只是换值。“换汤不换药” + // 用后继节点替换到要删除节点的位置。 然后就变成删除后继节点的问题了。为了逻辑统一 代码书写简洁。我们把后继节点赋给了p + p->data = minP->data; //将minP的值替换到p中 + //将p换到叶节点上,使用叶节点方法进行删除, 而且最小节点肯定没有左节点,叶节点删除方法参见后面的代码。 + p = minP; + pp = minPP; + } + + //删除节点是叶节点或者是仅有一个节点 + treeNode *child; + if (p->left != NULL) + child = p->left; + else if (p->right != NULL) + child = p->right; + else + child = NULL; + + if (NULL == pp) + root = child; //删除的是根节点 + else if (p == pp->left) + pp->left = child; + else + pp->right = child; + } }; int main() { - binary_search_tree my_tree; + binarySearchTree my_tree; - my_tree.insert_data(5); - my_tree.insert_data(4); - my_tree.insert_data(6); - my_tree.insert_data(10); - my_tree.insert_data(3); - my_tree.insert_data(8); - my_tree.insert_data(1); - if (my_tree.find_data(3)) - { - cout << "ҵ3" << endl; - } - else - { - cout << "ûҵ3" << endl; - } - my_tree.delet(4); - cout << "Max" << my_tree.get_max() << endl; - cout << "Min" << my_tree.get_min() << endl; - cout << "pre node of 5 is " <