1、二叉排序树特征
二叉排序树又称二叉搜索树,满足下列特征:
- 若根节点的左子树非空,则左子树上的所有节点关键字均小于根节点关键字;
- 若根节点的右子树非空,则右子树上的所有节点关键字均大于根节点关键字;
- 根节点的左、右子树本身又是二叉排序树。
在此,讨论节点为整型的二叉排序树。
typedef struct bstnode {
int data;
struct bstnode *left;
struct bstnode *right;
}BSTNode; //节点结构
2、插入
bool InsertBST(BSTNode *&bt, int k) {
//注意bt为引用类型
if (bt == nullptr) {
bt = (BSTNode*)malloc(sizeof(BSTNode));
bt->data = k; bt->left = nullptr; bt->right = nullptr;
return true;
}
else if (bt->data == k)
return false;
else if (bt->data > k)
return InsertBST(bt->left, k);
else
return InsertBST(bt->right, k);
}
3、创建
BSTNode* CreateBSTree(int A[], int n) {
BSTNode *bt = nullptr;
for (int i = 0; i < n; ++i)
InsertBST(bt, A[i]);
return bt;
}
4、查找
BSTNode *SearchBST(BSTNode *bt, int k) {
if (bt == nullptr)
return nullptr;
if (bt->data == k)
return bt;
else if (bt->data < k)
return SearchBST(bt->right, k);
else
return SearchBST(bt->left, k);
}
5、删除节点
/*
删除节点过程分以下几种情况
1、若p是叶子节点,直接删除
2、若p节点只有左子树而无右子树,可用其左孩子节点代替p
3、若p节点只有右子树而无左子树,将其右孩子节点替代p
4、若p节点同时有左右子树,选择左子树中最大的节点用其替代p,然后删除左子树最大的节点(第2种情况)
*/
void Delete(BSTNode *&bt);
void Delete1(BSTNode *&bt, BSTNode *&b);
bool DeleteBST(BSTNode *&bt, int k) {
if (bt == nullptr)
return false;
else {
if (bt->data < k)
DeleteBST(bt->right, k);
else if (bt->data > k)
DeleteBST(bt->left, k); //递归查找节点
else {
Delete(bt);
return true;
}
}
}
void Delete(BSTNode *&bt) {
BSTNode *p;
if (bt->left == nullptr) {//左孩子为空
p = bt;
bt = bt->right;
free(p);
}
else if (bt->right == nullptr) {//右孩子为空
p = bt;
bt = bt->left;
free(p);
}
else {
Delete1(bt,bt->left);//左右均不空
}
}
void Delete1(BSTNode *&bt, BSTNode *&b) {
BSTNode *p;
if (b->right != nullptr)
Delete1(bt, b->right); //找左孩子节点中最大的
else {
bt->data = b->data;
p = b;
b = b->left; //由于参数是传引用,因此这里代表原来指向b的父节点现在指向b的左孩子
free(p);
}
}