点击查看代码
#include<cstdio>
#pragma warning(disable:4996)
//二叉查找树的基本操作
//结点定义
struct node {
int data; //结点权值
node* lchild; //左孩子指针
node* rchild; //有孩子指针
};
//新建结点,结点权值为x
node* newNode(int x) {
node* Node = new node; //申请新结点的内存
Node->data = x; //结点权值为x
Node->lchild = Node->rchild = NULL; //初始状态下没有左右孩子
return Node; //返回新建结点的地址
}
//查找权值为x的结点
void search(node* root, int x) {
if (root == NULL) { //到达空结点,查找失败
printf("search failed\n");
return; //结束递归,返回上一层
}
if (x == root->data) { //查找成功
printf("%d\n", root->data);
}
else if (x < root->data) { //x比根结点的权值小
search(root->lchild, x); //进入左子树中查找
}
else { //x比根结点的权值大
search(root->rchild, x); //进入右子树中查找
}
}
//插入权值为x的新结点,root地址会被修改,要使用引用型
void insert(node*& root, int x) {
if (root == NULL) { //到达空结点,查找失败,在该位置插入新结点
root = newNode(x); //调用newNode()创建权值为x的新结点,将地址赋给root
return; //结束递归返回上一层
}
if (x == root->data) { //查找成功,结点已存在,不需要重复插入
return; //结束递归返回上一层
}
else if (x < root->data) { //权值x小于根结点的权值
insert(root->lchild, x); //进入左子树中查找插入位置
}
else { //权值x大于根结点的权值
insert(root->rchild, x); //进入右子树中查找插入位置
}
}
//二叉查找树的建立
node* create(int data[], int n) {
node* root = NULL; //新建根结点,初始为空地址
for (int i = 0; i < n; i++) { //依次将a[0]~a[n-1]插入二叉查找树中
insert(root, data[i]);
}
return root; //返回根结点地址
}
//查找以root为根结点的树中的最大权值结点
node* findMax(node* root) {
while (root->rchild != NULL) {
root = root->rchild; //不断往右子树中查找,直到没有右孩子
}
return root; //返回最大权值结点
}
//查找以root为根结点的树中的最小权值结点
node* findMin(node* root) {
while (root->lchild != NULL) {
root = root->lchild; //不断往左子树中查找,直到没有左孩子
}
return root; //返回最小权值结点
}
//删除以root为根结点的树中权值为x的结点
void deleteNode(node*& root, int x) {
if (root == NULL) return; //1、不存在权值为x的结点
if (root->data == x) { //2、找到权值为x的结点
if (root->lchild == NULL && root->rchild == NULL) { //2.1、该结点是叶子结点
root = NULL; //直接删除即可,将结点指向空地址
}
else if (root->lchild != NULL) { //2.2、该结点左子树非空
node* pre = findMax(root->lchild); //查找root的前驱结点
root->data = pre->data; //用前驱结点的权值覆盖待删除结点权值
deleteNode(root->lchild, pre->data); //然后在左子树中删除前驱结点pre
}
else { //2.3、该结点右子树非空
node* next = findMin(root->rchild); //查找root的后继结点
root->data = next->data; //用后继结点的权值覆盖待删除结点权值
deleteNode(root->rchild, next->data); //然后在右子树中删除后继结点next
}
}
else if (x < root->data) { //3、待删除权值x小于当前根结点权值
deleteNode(root->lchild, x); //进入左子树中查找待删除结点位置
}
else { //4、待删除权值x大于当前根结点权值
deleteNode(root->rchild, x); //进入右子树中查找待删除结点位置
}
}