建立一个二叉查找树,包含查找、插入、删除等基本操作,最后打印出这棵树建好树以及删除一个结点后的先序遍历的结果。
输入: 用数组data[10] = {5, 1, 8, 0, 3, 6, 9, 2, 4, 7} 创建BST;
要删除的数为: 5 ;
输出:
#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
/* struct BTree */
typedef struct BTNode{
Elemtype data;
struct BTNode *lchild, *rchild;
}BTree;
/* initialize BTree Node */
BTree* newBTNode(Elemtype x){
BTree *_btnode;
_btnode = (BTree*)malloc(sizeof(BTree));
_btnode->data = x;
_btnode->lchild = NULL;
_btnode->rchild = NULL;
return _btnode; //返回的是地址
}
/* preorder traversal */
void preorder(BTree* root){
if(root != NULL){
printf("%d ", root->data);
preorder(root->lchild);
preorder(root->rchild);
}
}
/* search */
void search(BTree *root, int x){
if(root == NULL){
printf("NULL!\n");
return;
}
if(x == root->data){
printf("Find %d\n", root->data);
}else if(x < root->data){
search(root->lchild, x);
}else{
search(root->rchild, x);
}
}
/* insert */
void insert(BTree* &root, int x){
if(root == NULL){ //插入的操作先看着为查找操作,而插入的地点就是查找失败的地点
root = newBTNode(x); //在查找失败的地方插入一个结点,并将其赋值为所要插入的值
return;
}
if(x == root->data){ //如果要插入的值已经存在,就直接返回
return;
}else if(x < root->data){ //如果插入的值比当前根根结点的值要小,就往左子树上面去找
insert(root->lchild, x);
}else{ //反之,就往右子树上面去找
insert(root->rchild, x);
}
}
/* create */
BTree* createBST(int data[], int n){
BTree* root = NULL;
for(int i = 0; i < n; i++){
insert(root, data[i]);
}
return root;
}
/* find precursor */
BTree* findPrecursor(BTree* root){
BTree* p = root->lchild; //在左子树寻找root的前驱
while(p->rchild != NULL){
p = p->rchild; //不断往右走,直到没有右孩子
}
return p;
}
/* find successor */
BTree* findSuccessorr(BTree* root){
BTree* p = root->rchild; //在右子树寻找root的前驱
while(p->lchild != NULL){ //不断往左走,直到没有左孩子
p = p->lchild;
}
return p;
}
/* deleteBSTNode */
void deleteBSTNode(BTree* &root, int x){
if(root == NULL) //要删除的结点不存在,直接返回
return;
if(root->data == x){ //找到要删除的结点后
if(root->lchild == NULL&& root->rchild == NULL){ //如果此结点是叶子结点,就直接删去
root = NULL;
}
else if(root->lchild != NULL){ //如果要删除的结点左子树,要先将它和它的前继交换位置,然后再删去
BTree *p = findPrecursor(root);
root->data = p->data; //通过交换data里的值来等价于交换结点
deleteBSTNode(root->lchild, p->data); //在左子树那里删去交换后的结点
}
else{
BTree *p = findSuccessorr(root);
root->data = p->data;
deleteBSTNode(root->rchild, p->data);
}
}else if(root->data > x){
deleteBSTNode(root->lchild, x);
}else{
deleteBSTNode(root->rchild, x);
}
}
int main(){
int data[10] = {5, 1, 8, 0, 3, 6, 9, 2, 4, 7};
BTree *root = createBST(data, 10);
preorder(root);
deleteBSTNode(root, 5);
printf("\n");
preorder(root);
return 0;
}