16 - 12 - 11 二叉排序树

来源:互联网 发布:网络咨询公司经营范围 编辑:程序博客网 时间:2024/04/29 08:42

二叉排序树:( BST : Binary_Sort_Tree )
设查找的数据集是普通的顺序存储,那么插入操作就是将记录放在表的末端,给表记录数加一即可,删除操作可以删除后,后面的记录向前移,也可以是要删除的元素与最后一个元素互换,表记录数减一,反正整个数据集也没有什么顺序,这样的效率也不错。应该说,插入和删除对于顺序存储结构来说,效率是可以接受的,但是这样的表由于无序造成查找的效率很低 如果查找的数据集是有序线性表,并且是顺序存储的,查找可以用折半、插值、斐波那契等查找算法来实现,可惜因为有序,在插入和删除操作上,就需要耗费大量的时间。有没有一种即可以使得插入和删除效率不错,又可以比高效率地实现查找的算法呢?

这里写图片描述

二叉排序树的查找要在一开始就建立一个排序树的存储结构。

/*查找,注意二重指针的巧妙利用*/typedef struct Binary{    int data;    struct Binary *lchild,*rchild}BiTNode,*BiTree;Status SearchBST(BiTree T,int key,BiTree f,BiTree *p)  {                                       //p是二重指针    if(!T){        *p = f;        return FALSE;    }else if(key == T->data){        *p = T;        return TRUE;    }else if(key < T->data){  //在左边找咯        return SearchBST(T->lchild,key,T,p);    }else{   //key > T->data,在右边找        return SearchBST(T->rchild,key,T,p);    }}/*当不存在这个 key 时,怒插一个在里面(手动滑稽)*/Status  InsertBST(BiTree T,int key){    BiTree p,s;    if( !SearchBST(*T, key, NULL, &p) )  //1、            {        s = (BiTree)malloc(sizeof(BiTNode));        s->data = key;        s->lchild = s->rchild = NULL;        if(!p){   //!p说明树不存在。。            *T= s;    //插入s为新的根节点        }else if(key < p->data)  //p有所指            p->lchild = s;        else //(key > p->data)            p->rchild = s;        return TRUE;    }    else        return FALSE;}//1、 因为p是二重指针,所以在内存里保存下来。    //search函数返回false时,if成立,说明要么这是个空树,    //要么因为最终到达树底也没找到该节点。比如你想找 9 这个    //节点,树中有一个叶节点8,那么下一步递归就去寻找8的    //右子树,8哪来的右子树?!自然递归过去的T->xchild为空    //进入if语句后,因为p = *T,若p不存在说明不存在树,    //然后巴拉巴拉~~~/*创建一个已知节点的树~~~*/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]);  //哈哈}/*删除较麻烦,保持二叉排序树不能从中间断掉,所以分类讨论*///1、一是删除叶子结点,很容易//2、而是删除只有左子树或只有右子树的节点,相对也比较好解决,//只需要将整个左右子树进行移动和删除即可,Status DeleteBST(BiTree *T,int key) //查找到key后删除{    if(!*T)        return FALSE;    else{        if(key == (*T)->data)            return Delete(T);  //delete在下面        else if(key < (*T)->data))            return DeleteBST(&(*T)->lchild,key) //key比较小,那一定在左边~        else            return DeleteBST(&(*T)->rchild,key)     }}Status Delete(BiTree *p) {    BiTree q,s;    if((*P)->rchild == NULL){  // 包含了所有叶子结点的情况        q = *p;  *p = (*p)->lchild; free(q);      }else if((*p)->lchild == NULL){   //说明只有右子树~        q = *p;  *p = (*p)->rchild; free(q);      }else{                //左右子树都不空        q = *p;  s = (*p)->lchild;        while(s->rchild)  //转一下左。再一直向右。看图~        {            q = s;  s = s->rchild;        }        (*p)->data = s->data;  //37覆盖47        if(q != *p)   //1、            q->rchild = s->lchild;  //重接 q 的右子树        else            q->lchild = s->lchild;  //重接 q 的右子树        free(s);    }       return TRUE;}//1、注意!q = *p的情况是:(*p)->lchild 没有左子树~

// ————-《大话数据结构》

1 0