二叉查找树的创建,查找,插入,删除等操作C语言

#include<stdio.h>
#include<stdlib.h>

typedef int type;
typedef struct bst                                                                  //创建结构体
{
    type data;
    struct bst *left, *right;
    struct bst *parent;
}node, *tree;



static node* create_node(type data, node *left, node *right, node *parent)                       //创建结点
{
    node *p;
    p = (node*)malloc(sizeof(node));

    p->left = left;
    p->right = right;
    p->parent = parent;
    p->data = data;
    /*  printf("创造结点完毕");*/
    return p;

}

node* search_(tree x, type key)
{
    if (x == NULL || x->data == key)
    {
        return x;
    }

    if (key < x->data)
    {

        return search_(x->left, key);
    }
    else

    {
        return search_(x->right, key);
    }


}                                                                  //递归查找


node* search(tree y, type key)
{

    while (y != NULL && y->data != key)
    {
        if (y->data < key)
            y = y->right;
        else
            y = y->left;
    }
    return y;
}                                                              //迭代查找


node* max(tree m)                       //最大值
{

    if (m == NULL)
        return NULL;
    while (m->right != NULL)
    {
        m = m->right;
    }
    return m;
}

node* min(tree m)                     //最小值
{

    if (m == NULL)
        return NULL;
    while (m->left != NULL)
    {
        m = m->left;
    }
    return m;
}

node* successor(node *s)           //后继
{


    if (s->right != NULL)             //结点右子树非空

        return  min(s->right);


    else
    {
        node* p = s->parent;                //结点是左孩子,后继就是他的父节点
        while (p != NULL && p->right == s)
        {                                       //结点是右孩子,向上查找,直到遇到一个有左孩子的父节点,那就是后继
            {
                s = p;
                p = p->parent;
            }

        }
        return p;
    }

}

node* insert(tree t, node *z)              //将建好的结点插入进二叉树里
{
    node *y = NULL;
    node *i;
    i = t;

    while (i != NULL)
    {
        y = i;                        //循环完了之后y是i的父节点
        if (i->data < z->data)
            i = i->right;
        else
            i = i->left;
    }
    z->parent = y;
    if (y == NULL)                         //整棵树在插入之前都是空的
        t = z;
    else if (z->data < y->data)
        y->left = z;
    else
        y->right = z;

    return t;



}

node* insert_(tree t, type k)                    //建立一个结点,没有连接
{
    node *z;
    z = create_node(k, NULL, NULL, NULL);


    return  insert(t, z);


}



node* deletes(tree d, node* z)                                           //删除
{
    tree x = NULL, y = NULL;

    if (z->left == NULL || z->right == NULL)                            //z至多有一个子女      
        y = z;
    else                                                                 //z有两个子女
        y = successor(z);
    if (y->left != NULL)                                                //y(也就是z,或z的后继)如果有子女,将它赋给x
        x = y->left;
    else
        x = y->right;
    if (x != NULL)                                                       //x如果得到了y赋的值(也就是z的子女或者后继的子女)
        x->parent = y->parent;
    if (y->parent == NULL)                                               //如果y是根节点
        d = x;
    else if (y == y->parent->left)                                         //如果y是左子女
        y->parent->left = x;
    else                                                                   //如果y是右子女
        y->parent->right = x;
    if (y != z)                                                            //y不等于z就是等于后继,z有两个子女的情况,就把后继的值拿给z
        z->data = y->data;
    return d;

}

node* delete_(tree t, type k)
{
    node* z=NULL;
    z = search_(t, k);

    if (z != NULL)
    {
        printf("查找");
        t = deletes(t, z);
        printf("删除完了");
    }
    else
        printf("无此元素");

    return t;
}


void print_tree(tree t)                        //中序遍历打印
{
    if (t)
    {
        print_tree(t->left);
        printf("%d      ", t->data);
        print_tree(t->right);
    }
}


int main()
{
    int i;
    tree zz = NULL, yy = NULL,kk=NULL,gg=NULL;
    type k;
    int a[12] = { 15,5,16,3,12,10,13,6,7,20,18,23 };
    printf("\n原来的数字是:----------------------------------------");
    for (i = 0; i<12; i++)
    {
        printf("%d ", a[i]);
        zz = insert_(zz, a[i]);

    }
    /* printf("插入完毕");*/
    printf("\n中序遍历结果是:------------------------------------");
    print_tree(zz);
    printf("\n最大值是:-------------------------------------------");
    printf("%d  ", max(zz)->data);
    printf("\n请输入要查找的值:--------------------------------");
    scanf_s("%d", &k);
    search_(zz, k);
    if (search_(zz, k) != NULL)
        printf("查找成功");
    else
        printf("无此元素");
    printf("\n要查找的后继是:---------------------------------");
    scanf_s("%d", &k);
    kk=search_(zz, k);
    gg=successor(kk);
    printf("%d", gg->data);
    printf("\n要删除的值是:---------------------------------------");
    scanf_s("%d", &k);
    yy = delete_(zz, k);
    print_tree(yy);
    printf("\n要插入的值是:--------------------------------------");
    scanf_s("%d", &k);
    insert_(zz, k);
    print_tree(zz);

}

参照了算法导论的伪代码和https://www.cnblogs.com/skywang12345/p/3576328.html这位博主的代码
感觉自己主函数写得好乱。。。。

猜你喜欢

转载自blog.csdn.net/alike_meng/article/details/82225019