查找(3)——二叉排序树的建立、结点的查找和删除

来源:互联网 发布:linux shell 小数比较 编辑:程序博客网 时间:2024/06/06 14:15
#include <stdio.h>#include <stdlib.h>typedef struct node{    int data;    node * lchild;    node * rchild;}BTree;void createBTree(BTree * root,int x){       //建立二叉排序树    BTree * q, * p;    q = root;    while(q != NULL){        if(q->data == x){            goto L1;        }else if(q->data > x){            p = q;            q = q->lchild;        }else{            p = q;            q = q->rchild;        }    }    q = (BTree *)malloc(sizeof(BTree));    q->data = x;    q->lchild = NULL;    q->rchild = NULL;    if(p->data > x){        p->lchild = q;    }else if(p->data < x){        p->rchild = q;    }L1: ;}BTree * searchBTree(BTree * root,int x){        //在二叉排序树中查找给定的数值,返回指向该数的指针    BTree * q = root;    while(q != NULL){        if(q->data == x){            return q;        }else if(q->data > x){            q = q->lchild;        }else{            q = q->rchild;        }    }    return NULL;}/*删除二叉排序树的一个结点需要考虑到:(1)空树-->退出(2)只有一个结点并且这个结点的值与待删除结点的值一致-->将该结点的指针置空(3)多于一个结点时,循环找到该结点并且分类考虑如何删除该结点(3.1)该结点时叶子结点(3.2)该结点只有左子树(3.3)该结点只有右子树(3.4)该结点即有左子树又有右子树*/void deleteBTree(BTree * root,int x){    BTree * p,* q,* r;    q = root;    if(q == NULL){        goto L1;    }else if(q->lchild == NULL && q->rchild == NULL && q->data == x){        q = NULL;        goto L1;    }else{        while(q != NULL){            if(q->data == x){                goto L2;            }else if(q->data > x){                p = q;                q = q->lchild;            }else{                p = q;                q = q->rchild;            }        }        if(q == NULL){            goto L1;        }    }L1: ;L2: if(q->lchild == NULL && q->rchild == NULL){     //当该结点是叶子结点        if(p->lchild == q){            p->lchild = NULL;        }else{            p->rchild = NULL;        }    }else if(q->lchild == NULL){        //当该结点只有右子树        if(p->lchild == q){            p->lchild = q->rchild;        }else{            p->rchild = q->rchild;        }    }else if(q->rchild == NULL){        //当该结点只有左子树        if(p->lchild == q){            p->lchild = q->lchild;        }else{            p->rchild = q->lchild;        }    }else{                              //当该结点即有左子树又有右子树        r = q->rchild;        if(r->rchild == NULL && r->lchild == NULL){     //如果待删除节点的右子树只有一个结点时,直接拷贝该值,并置该结点的右指针为空            q->data = r->data;                      q->rchild = NULL;        }else{            p = q;            while(r->lchild != NULL){           //while循环的目的是找到该结点右子树的最左边的结点                p = r;                r = r->lchild;            }            q->data = r->data;            if(p->lchild == r){         //当找到最左边的结点时,相当于删除一个无左子树的结点                p->lchild = r->rchild;            }else{                p->rchild = r->rchild;            }        }    }}void inOrder(BTree * root){     //中序递归遍历二叉排序树    if(root != NULL){        inOrder(root->lchild);        printf("%d ",root->data);        inOrder(root->rchild);    }}int main(){    BTree * root, * q;    int n,x,k,t;    printf("请输入结点的个数。\n");    scanf("%d",&n);    printf("请输入结点的数值。\n");    for(int i=0;i<n;i++){        scanf("%d",&x);        if(i == 0){            root = (BTree *)malloc(sizeof(BTree));            root->data = x;            root->lchild = NULL;            root->rchild = NULL;        }else{            createBTree(root,x);        }    }    printf("二叉排序树中所有的值为:\n");    inOrder(root);    printf("\n");    printf("请输入要查找的数。\n");    scanf("%d",&k);    while(k != -1){        q = searchBTree(root,k);        if(q == NULL){            printf("二叉排序树中没有该数。\n");        }else{            printf("找到要查找的数%d\n",q->data);        }        printf("请输入要查找的数。\n");        scanf("%d",&k);    }       printf("请输入要删除的数\n");    scanf("%d",&t);    deleteBTree(root,t);    printf("删除后的结果是:\n");    inOrder(root);    return 0;}
0 0
原创粉丝点击