Merge pull request #308 from zwkcoding/from_zwkcoding/bugfix
fix bug in binary_search_tree
This commit is contained in:
commit
f8ed2480bf
@ -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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user