DataStructure-8.1-二叉排序树

来源:互联网 发布:类似于知乎的网站 编辑:程序博客网 时间:2024/06/08 20:34

8.1二叉排序树

     二叉排序树又称二叉查找树,它或者是一棵空的二叉树,或者是具有以下性质的二叉树:

    (1) 若它的左子树不空,则左子树上所有结点的值均小于根结点的值.

    (2) 若它的右子树不空,则右子树上所有结点的值均大于根结点的值.

    (3)  它的左右子树也都是二叉排序树.

8.2 二叉排序树的实现

 BiSortTree.h

   #ifndef BISORTTREE_H
#define BISORTTREE_H

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

typedef int DataType;

typedef struct BiNode
{     
    DataType data;
    struct BiNode *lchild,*rchild;
}BiNode,*BiTree;

void CreateBiSortTree(BiTree *bt,DataType r[],int n);
void InsertBST(BiTree *bt,DataType e);
BiNode* DeleteBST(BiTree *bt,DataType e); //查找要删除的结点
void Delete(BiNode *p);  //删除节点
BiNode* SearchBST(BiTree *bt,DataType e);
void InOrder(BiTree *bt); //中序遍历
    
#endif


BiSortTree.c


#include "BiSortTree.h"

void CreateBiSortTree(BiTree *bt,DataType r[],int n)
{
    //初始化二叉排序数的根结点
    //*bt = (BiTree)malloc(sizeof(BiNode));
    *bt = NULL;

    BiNode *s;
    int i;
    //依次取记录r[i]的值
    for(i=0;i<n;i++)
    {
        //将结点插入到二叉排序数中
        InsertBST(bt,r[i]);
    }
}

void InsertBST(BiTree *bt,DataType e)
{
    //如果是空树,将结点s作为根结点插入
    if((*bt) == NULL)
    {
        (*bt) = (BiTree)malloc(sizeof(BiNode));
        (*bt)->data = e;
        (*bt)->lchild = (*bt)->rchild = NULL;
    }
    //否则,如果s->data < (*bt)->data,则把节点插入到*bt的左子树
    else if(e < ((*bt)->data))
    {
        InsertBST(&((*bt)->lchild),e);
    }
    //否则,如果s->data >= (*bt)->data,则把节点插入到*bt的右子树
    else{
        InsertBST(&((*bt)->rchild),e);
    }
}

BiNode* DeleteBST(BiTree *bt,DataType e)
{
    //若*bt为空树,则查找失败
    if(*bt == NULL)
    {
        return NULL;
    }
    //否则,如果e等于(*bt)->data,则查找成功,进行删除操作
    else if((*bt)->data == e)
    {
        Delete(*bt);
    }
    //否则,如果e<(*bt)->data,则继续查找(*bt)的左子树
    else if((*bt)->data > e){
        return DeleteBST(&(*bt)->lchild,e);
    }
    //否则,如果e>(*bt)->data,则继续查找(*bt)的右子树
    else{
        return DeleteBST(&(*bt)->rchild,e);
    }

}
void Delete(BiNode *p)
{
    BiNode *q,*s;

    /*若结点p左子树为空(即只有右子树),则只需重建p的右子树*/
    if(p->lchild == NULL)
    {
        q = p;
        p=p->rchild;
        free(q);
    }
    /*若结点p右子树为空(即只有左子树),则只需重建p的左子树*/
    else if(p->rchild == NULL)
    {
        q=p;
        p=p->lchild;
        free(q);
    }
    /*结点p左右子树都不为空*/
    else
 else
    {
        q = p;
        s = p->lchild;
        //查找p的前驱结点
        while(s->rchild != NULL)
        {
            q = s;
            s = s->rchild;
        }
        //将前驱结点的data覆盖到要删除的结点p上
        p->data = s->data;
        //若s的右子树有结点,则将拆去的s结点的左孩子链接到q的右孩子上
        if(q != p)
        {
            q->rchild=s->lchild;
        }
        //若s的右孩子为空,则直接将s的左孩子链接到q的左孩子上
        else{
            q->lchild = s->lchild; 
        }
        free(s);
   }
}

BiNode* SearchBST(BiTree *bt,DataType e)
{
    //若*bt为空树,则查找失败
    if(*bt == NULL)
    {
        return NULL;
    }
    //否则,如果e等于(*bt)->data,则查找成功
    else if((*bt)->data == e)
    {
        return *bt;
    }
    //否则,如果e<(*bt)->data,则继续查找(*bt)的左子树
    else if((*bt)->data > e){
        return SearchBST(&(*bt)->lchild,e);
    }
    //否则,如果e>(*bt)->data,则继续查找(*bt)的右子树
    else{
        return SearchBST(&(*bt)->rchild,e);
    }

}

void InOrder(BiTree *bt)
{
    if(*bt == NULL)
    {
        return ;
    }
    else{

        InOrder(&(*bt)->lchild);
        printf("%d\n",(*bt)->data);
        InOrder(&(*bt)->rchild);
    }
}


main.c

#include <stdio.h>
#include "BiSortTree.h"

int main(void)
{
    BiTree B;
    int r[]={10,15,23,5,7,14,25,30};

    CreateBiSortTree(&B,r,8);
    InOrder(&B);

    printf("mmmmmmmmmmm:%d\n",SearchBST(&B,7)->data);

    InOrder(&B);
    DeleteBST(&B,7);
    printf("Delete after........\n");
    InOrder(&B);
    return 0;
}



0 0