二叉搜索树

277 阅读3分钟
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 100

typedef int Status;

//二叉树链式存储结构
typedef struct BiTNode{
    //结果数据
    int data;
    //左孩子
    struct BiTNode *lchild;
    //右孩子
    struct BiTNode *rchild;
}BiTNode, *BiTree;

//1.二叉排序树--查找
//递归查找二叉排序树T中,是否存在key
//f指向T的双亲
Status SearchBST(BiTree T,int key,BiTree f,BiTree *p){
    if (!T) {
        //没有找到,返回叶子结点
        *p = f;
        return FALSE;
    }else if (key == T->data){
        *p = T;
        return TRUE;
    }else if (key < T->data){
        //key小于当前结点,则继续查找左子树
        return SearchBST(T->lchild, key, T, p);
    }else{
        //key大于当前结点,则继续查找右子树
        return SearchBST(T->rchild, key, T, p);
    }
}
//2.二叉排序树-插入
//
Status InsertBST(BiTree *T,int key){
    BiTree p,s;
    //1.查找插入的值key是否存在二叉树中
    if (!SearchBST(*T, key, NULL, &p)) {
        //key在树中不存在,p返回的是叶子结点
        //2.创建新结点
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        
        if (!p) {
            //p为空,说明树中无结点,将s设置为根结点
            *T = s;
        }else if(key < p->data){
            //key 小于p的值,将key放在p的左子树
            p->lchild = s;
        }else{
            //key 大于p的值,将key放在p的右子树
            p->rchild = s;
        }
        return TRUE;
    }

    return FALSE;
}
//3.删除结点p,并重接它的左右子树
Status Delete(BiTree *p){
    BiTree temp,s;
    if ((*p)->lchild == NULL) {
        //如果左子树为空,并将p删除,p接上右子树
        temp = *p;
        *p = (*p)->rchild;
        free(temp);
    }else if ((*p)->rchild == NULL){
        //如果右子树为空,并将p删除,p接上左子树
        temp = *p;
        *p = (*p)->lchild;
        free(temp);
    }else{
        //左右子树都不为空的情况
        //先指向*p
        temp = *p;
        //s指向p的左子树
        s = (*p)->lchild;
        //找到s的最后一个右子树
        while (s->rchild) {
            temp = s;//temp一直都指向s的双亲
            s = s->rchild;
        }
        //将p的左子树的最后一个右子树的值赋给p,这样p原来的值就删除了
        (*p)->data = s->data;
        
        if (temp != *p) {
            //这种情况是p的左子树有右子树
            temp->rchild = s->lchild;
        }else{
            //这种情况是p的左子树没有右子树
            temp->lchild = s->lchild;
        }
        //s的值已经赋给了p,s是多余的,删除s
        free(s);
    }
    return TRUE;
}

//4.查找结点,并将其在二叉树排序中删除
//如果树中存在data = key的结点,则删除,并返回TRUE,否则返回FALSE
Status DeleteBST(BiTree *T,int key){
    //如果树为空
    if (*T == NULL) {
        return FALSE;
    }else{
        if ( (*T)->data == key ) {
            //找到了,去删除它
            return Delete(T);
        }else if (key < (*T)->data ){
            //查找左子树
           return DeleteBST(&(*T)->lchild, key);
        }else{
            //查找右子树
           return DeleteBST(&(*T)->rchild, key);
        }
    }
}

int main(int argc, const char * argv[]) {
    printf("Hello, 二叉排序树(Binary Sort Tree)!\n");
    int i;
    int a[10] = {62,88,58,47,35,73,51,99,37,93};
    BiTree T = NULL;
    for (i=0; i<10; i++) {
        InsertBST(&T, a[i]);
    }
    
    BiTree p;
    int statusValue = SearchBST(T, 99, NULL, &p);
    printf("查找%d是否成功:%d (1->YES/0->NO)\n",p->data,statusValue);
    
    statusValue = DeleteBST(&T,99);
    printf("二叉排序树删除99是否成功:%d (1->YES/0->NO)\n",statusValue);
    
    statusValue = SearchBST(T, 99, NULL, &p);
    printf("查找%d是否成功:%d (1->YES/0->NO)\n",99,statusValue);

    return 0;
}