二叉排序树

来源:互联网 发布:淘宝卖点文案 编辑:程序博客网 时间:2024/06/17 01:03

二叉排序树 (BST) :

建立在二叉树基础上,性质如下

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结构的值
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结构的值
  • 它的左子树和右子树都是二叉排序树
  • 故左子树所有结点一定比父结点小,右子树所有结点一定比父结点大 
查找,近乎析半查找,输出采用中序遍历,可获取从大到小序列
构造一颗二叉排序树的目的,其实并不是为了排序,而是为了提高查找和插入删除关键字的速度。

代码示例:
创建:输入前序排列的数组
PNODE creatree(PNODE *tr,int a[]){    //coutleft,a);            n++;            creatree(&(*tr)->right,a);        }}

插入:
int inserttr(PNODE *tr,int a)//注意形参为指针的指针,若PNODE tr的话无法传回tre{    if(*tr==NULL)    {        *tr=new NODE;        (*tr)->inode=a;//(*tr)加括号        (*tr)->left=NULL;        (*tr)->right=NULL;    }    else{        if((*tr)->inode>a)        {            inserttr(&(*tr)->left,a);        }        else if((*tr)->inoderight,a);        }    }    return 1;}
该节点若是空,插入即可,
非空,小于该节点值,再插入左子树,否则,插入右子树,等于该节点值,则不执行;并不会引起二叉树其他部分的结构变化
查找:
PNODE* findq(PNODE *tr,int a)//查找不成功返回-1;其他返回1;{    if((*tr)==NULL)       {        return NULL;       }    else if((*tr)->inode==a)        return tr;    else    {        if((*tr)->inode>a)        {            return findq(&(*tr)->left,a);//层层返回消息        }        else        {            return findq(&(*tr)->right,a);        }    }}
该节点若是空,返回,
非空,小于该节点值,入左子树查找,大于该节点,入右子树查找,等于该节点,即找到

删除:代码块一直显示empty,不知为啥,只有直接贴出来了;此代码验证无误,有许多博客写的不全面或是错的
int deletetr(PNODE *tr,int a){    PNODE *c=(findq(tr,a));    PNODE s,q;    if(c==NULL)        return NULL;    if(((*c)->left!=NULL)&&((*c)->right!=NULL))//被删除节点有左右子树    {        q=*c;        s=(*c)->left;        while((s)->right)//寻找左子树最右节点        {            q=s;            s=(s)->right;        }        (*c)->inode=(s)->inode;//交换被删除节点与最右节点的值,子树指针保留,这样操作比较方便        //最右节点可能存在左子树,将其保留,但注意:        if(q==(*c))//此时,新节点就是被删除节点的左子树根            q->left=s->left;        else            q->right=s->left;        delete s;    }    else if(((*c)->left==NULL)&&((*c)->right==NULL))    {        q=*c;        (*c)=NULL;        delete q;    }    else    {        if((*c)->left!=NULL)        {            q=*c;            (*c)=(*c)->left;            delete q;        }        else        {            q=*c;            (*c)=(*c)->right;            delete q;        }    }    return 1;}




叶子节点直接删除;
有一个子树上移连接即可;
两个子树,两种方法
1.用被删结点左子树最右下的结点的值代替被删结点的值,然后删去最右下的结点,即直接前驱
2.用被删结点右子树最左下的结点的值代替被删结点的值,然后删去最左下的结点,即直接后继
为啥可以这样?直接前驱或者直接后继,就是数值上最贴近被替换节点的值,故直接替换值即可,被替换节点的左右子树指针不变,注意指针操作
我们采用方法1
主函数:中序遍历函数参见二叉树内容
typedef struct node{    int inode;    node *left;    node *right;}NODE ,*PNODE;int main(){   int a[7]={12,10,'%','%',19,'%','%'};    PNODE tre;    creatree(&tre,a);//前序排列初始化一个树;%表示无节点    midout(tre);//    cout<

结果:





原创粉丝点击