Merge pull request #308 from zwkcoding/from_zwkcoding/bugfix

fix bug in binary_search_tree
This commit is contained in:
wangzheng0822 2019-05-09 08:49:43 +08:00 committed by GitHub
commit f8ed2480bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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 <iostream> #include <iostream>
using namespace std; using namespace std;
typedef int DataType; typedef int DataType;
struct tree_node struct treeNode
{ {
DataType data; DataType data;
tree_node* left=NULL; treeNode *left = nullptr;
tree_node* right=NULL; treeNode *right = nullptr;
}; };
class binary_search_tree{ class binarySearchTree
{
private: private:
tree_node* root; treeNode *root;
int num; int num; // tree node numbers
public: public:
binary_search_tree() :num(0) binarySearchTree() : num(0)
{ {
root = new tree_node; root = new treeNode;
root->left = NULL; root->left = nullptr;
root->right = NULL; root->right = nullptr;
} }
bool find(DataType it,tree_node* root) bool find(DataType it, treeNode *root)
{ {
if (NULL == root)return false; if (nullptr == root)
if (it == root->data) { return false;
return true; if (it == root->data) {
} return true;
else if (it > root->data) } else if (it > root->data) {
{ return find(it, root->right);
return find(it, root->right); } else {
} return find(it, root->left);
else }
{ }
return find(it, root->left);
}
}
bool find_data(DataType it) bool find_data(DataType it)
{ {
return find(it, root); return find(it, root);
/* /*
tree_node* p = root; treeNode* p = root;
while (p != NULL) while (p != nullptr)
{ {
if (it < p->data)p = p->left; if (it < p->data)p = p->left;
else if (it>p->data)p = p->right; else if (it>p->data)p = p->right;
@ -52,217 +59,233 @@ public:
} }
return false; 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) void insert_data(DataType it)
{ // 利用二分查找的思想,借助树的结构使用递归
root->data = it; {
num++; if (0 == num) {
return; root->data = it;
} num++;
tree_node* p = root; return;
while (p != NULL) }
{ treeNode *p = root;
if (it < p->data) while (p != nullptr) {
{ if (it < p->data) {
if (NULL == p->left) if (nullptr == p->left) {
{ p->left = new treeNode;
p->left = new tree_node; p->left->data = it;
p->left->data = it; num++;
num++; return;
return; }
} p = p->left;
p = p->left; } else {
} if (nullptr == p->right) {
else p->right = new treeNode;
{ p->right->data = it;
if (NULL == p->right) num++;
{ return;
p->right = new tree_node; }
p->right->data = it; p = p->right;
num++; }
return; }
} }
p = p->right;
}
}
}
void delet(DataType it) DataType get_prenode(DataType it)
{ {
if (NULL == root)return; if (nullptr == root)
tree_node* p = root; return NULL;
tree_node* pp = NULL;//pp记录的是p的父节点 if (it == root->data)
while (p != NULL&&p->data != it) return NULL;
{ treeNode *p = root;
pp = p; treeNode *pp = nullptr;
if (it > p->data)p = p->right; while (p != nullptr) {
else if (p->data < it) {
p = p->left; pp = p; // label parent root
} p = p->right;
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;
}
//删除节点是叶节点或者是仅有一个节点 } else if (p->data > it) {
tree_node* child; pp = p; // label parent root
if (p->left != NULL) child = p->left; p = p->left;
else if (p->right != NULL) child = p->right; } else {
else child = NULL;
if (NULL == pp) root = child;//删除的是根节点 break;
else if (p == pp->left)pp->left = child; }
else pp->right = child; }
} return ((nullptr == p) ? NULL : pp->data);
}
DataType get_max() DataType get_postnode(DataType it)
{ {
if (NULL == root)return NULL; if (nullptr == root)
tree_node* tmp=root; return -1;
while (tmp->right != NULL) treeNode *p = root;
{ while (p != nullptr) {
tmp = tmp->right; if (p->data < it) {
} p = p->right;
return tmp->data; } else if (p->data > it) {
} p = p->left;
DataType get_min() } else {
{ break;
if (NULL == root)return NULL; }
tree_node* tmp=root; }
while (tmp->left != NULL) if (nullptr == p) {
{ return -1;
tmp = tmp->left; } else if (p->left != nullptr) {
} return p->left->data;
return tmp->data; } else if (p->right != nullptr) {
} return p->right->data;
} else {
return NULL;
}
}
DataType get_prenode(DataType it) void mid_order(treeNode *rt)
{ {
if (NULL == root)return NULL; if (nullptr == rt)
if (it == root->data) return NULL; return;
tree_node* p=root; mid_order(rt->left);
tree_node* pp=NULL; cout << rt->data << '\t';
while ((p->data != it)&&(p!=NULL)) mid_order(rt->right);
{ }
pp = p;
if (p->data < it)
{
p=p->right;
}
else
{
p = p->left;
}
}
return ((NULL==p)?NULL:pp->data);
}
DataType get_postnode(DataType it) void order()
{ {
if (NULL == root)return -1; if (nullptr == root)
tree_node* p = root; return;
while ((p->data != it) && (p != NULL)) return mid_order(root);
{ }
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 mid_order(tree_node* rt) int get_high(treeNode *rt)
{ {
if (NULL == rt)return; int lhigh = 0;
mid_order(rt->left); int rhigh = 0;
cout << rt->data; if (nullptr == rt)
mid_order(rt->right); return 0;
} lhigh = get_high(rt->left);
void order() rhigh = get_high(rt->right);
{ return ((lhigh > rhigh) ? (lhigh + 1) : (rhigh + 1));
if (NULL == root)return; }
return mid_order(root);
}
int get_high(tree_node* rt) int high()
{ {
int lhigh = 0; if (nullptr == root)
int rhigh = 0; return 1;
if (NULL == rt)return 0; return get_high(root);
lhigh = get_high(rt->left); }
rhigh = get_high(rt->right);
return ((lhigh > rhigh) ? (lhigh + 1) : (rhigh + 1));
}
int high() void delet(DataType it)
{ {
if (NULL == root) return 1; if (NULL == root)
return get_high(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() int main()
{ {
binary_search_tree my_tree; binarySearchTree my_tree;
my_tree.insert_data(5); // must input in the order of layers
my_tree.insert_data(4); my_tree.insert_data(33);
my_tree.insert_data(6); my_tree.insert_data(16);
my_tree.insert_data(10); my_tree.insert_data(50);
my_tree.insert_data(3); my_tree.insert_data(13);
my_tree.insert_data(8); my_tree.insert_data(18);
my_tree.insert_data(1); my_tree.insert_data(34);
if (my_tree.find_data(3)) my_tree.insert_data(58);
{ my_tree.insert_data(15);
cout << "找到了数字3" << endl; my_tree.insert_data(17);
} my_tree.insert_data(25);
else my_tree.insert_data(51);
{ my_tree.insert_data(66);
cout << "没有找到数字3" << endl; my_tree.insert_data(19);
} my_tree.insert_data(27);
my_tree.delet(4); my_tree.insert_data(55);
cout << "Max" << my_tree.get_max() << endl;
cout << "Min" << my_tree.get_min() << endl; if (my_tree.find_data(25)) {
cout << "pre node of 5 is " <<my_tree.get_prenode(5) <<endl; cout << "找到了数字25" << endl;
cout << "post node of 5 is " << my_tree.get_postnode(5) << endl; } else {
my_tree.order(); cout << "没有找到数字25" << endl;
cout << "high of tree is " << my_tree.high() << endl; }
return 0; my_tree.delet(13);
} my_tree.delet(18);
my_tree.delet(55);
cout << "Max: " << my_tree.get_max() << endl;
cout << "Min: " << my_tree.get_min() << endl;
cout << "pre node of 17 is " << my_tree.get_prenode(17) << endl;
cout << "pre node of 51 is " << my_tree.get_prenode(51) << endl;
cout << "pre node of 33 is " << my_tree.get_prenode(33) << endl;
cout << "post node of 19 is " << my_tree.get_postnode(19) << endl;
cout << "post node of 25 is " << my_tree.get_postnode(25) << endl;
cout << "post node of 58 is " << my_tree.get_postnode(58) << endl;
cout << "post node of 58 is " << my_tree.get_postnode(51) << endl;
my_tree.order();
cout << "high of tree is " << my_tree.high() << endl;
return 0;
}