二叉排序树的建立、结点插入及删除

#include<stdio.h>
#include<stdlib.h>
#define  STATUS int
#define  FAIL 0
#define  SUCCESS 1

typedef struct bstnode//定义排序二叉树结点结构体
{
    int data;
    struct bstnode *lchild,*rchild;
}bstnode,*bstptr;

void bitinsert(bstptr *thead,int elm)//二叉排序树插入节点
{
    bstptr temp;
    if (*thead==NULL)//没有后续节点
    {
        temp = (bstptr)malloc(sizeof(bstnode));
        temp->data = elm;//初始化二叉树结点
        temp->lchild = NULL;
        temp->rchild = NULL;
        *thead = temp;//完成节点插入;
    }
    else if(elm<(*thead)->data)
    {
        bitinsert(&(*thead)->lchild,elm);
    }
    else if(elm>(*thead)->data)
    {
        bitinsert(&(*thead)->rchild,elm);
    }
    else
        return;

}
void InOrderTranverse(bstptr thead)//中序遍历
{
    if (thead==NULL)//
    {
        return;
    }
    else
    {
        InOrderTranverse(thead->lchild);//遍历左子树
        printf("%p,%d\n",thead,thead->data);//打印根结点
        InOrderTranverse(thead->rchild);//遍历右子树
    }
}

STATUS BST_Search(bstptr bsthead,int key,bstptr *keyptr)//二叉排序树查找
{
    if (bsthead==NULL)//没有找到
    {
        *keyptr = NULL;
        return FAIL;
    }
    else if(key ==bsthead->data)//找到
    {
        *keyptr = bsthead;//返回对应地址
        return SUCCESS;
    }
    else if(key <bsthead->data)
    {
        BST_Search(bsthead->lchild,key,keyptr);//遍历左子树
    }
    else if(key >bsthead->data)
    {
        BST_Search(bsthead->rchild,key,keyptr);//遍历右子树
    }
}

STATUS BST_Delete(bstptr bsthead,int key)//删除结点,先查找,找到后再删除
{
    if(bsthead==NULL)
    {
        return FAIL;
    }
    else if(key == bsthead->data)//找到该结点
    {
        return Delete(&bsthead);//删除该结点
    }
    else if(key < bsthead->data)//找到该结点
    {
        BST_Delete(bsthead->lchild,key);//删除值比
    }
    else if(key > bsthead->data)//找到该结点
    {
        BST_Delete(bsthead->rchild,key);                
    }


}

STATUS Delete(bstptr * t)//传输的是指针域的地址,直接修改lchild or rchild
{
    bstptr q,s;
    if((*t)->lchild==NULL)//左子树为空,连接右子树
    {
        q = *t;
        (*t) = (*t)->rchild;//连接右子树,直接改变指针
        free(q);//删除结点所占空间
    }
    else if((*t)->rchild==NULL)//右子树为空,连接左子树
    {
        q = *t;
        (*t) = (*t)->lchild;//连接左子树,直接改变指针
        free(q);//删除结点所占空间
    }
    else//有两个孩子
    {
        q = (*t);//找到中序遍历时的前驱结点,即孩子结点的右子树最右边的叶子结点
        s = (*t)->lchild;
        while(s->rchild!=NULL)
        {
            q = s;//记录当前结点值
            s = s->rchild;//找到右子树最右边的叶子结点
        }
        (*t)->data = s->data;
        if (q==*t)//孩子结点为目标结点
        {
            q->lchild = s->lchild;//链接
        }
        else//存在右子树
        {
            q->rchild = s->lchild;//目标结点的父亲结点链接孩子结点
        }
        free(s);


    }
    return SUCCESS;
}

void main()
{
    int i;//计数
    bstptr keyptr = NULL;
    int a[]={62,88,58,47,35,73,51,99,37,93};
    bstptr bsthead=NULL;
    //bitinsert(&bsthead,1);
    //bitinsert(&bsthead,2);
    //bitinsert(&bsthead,3);
    //bitinsert(&bsthead,4);
    //bitinsert(&bsthead,4);
    for (i=0;i<10;i++)
    {
         bitinsert(&bsthead,a[i]);  
    }
    InOrderTranverse(bsthead);
    if(BST_Search(bsthead,99,&keyptr))
    {
        printf("\n%p,%d\n\n",keyptr,keyptr->data);
    }
    if( BST_Delete(bsthead,30))
    {
        InOrderTranverse(bsthead);
    }
    else
    {
        printf("key:%d is not in the tree\n");
    }
    getchar();
}

猜你喜欢

转载自blog.csdn.net/thriveluo/article/details/48895073
今日推荐