顺序二叉树的建立、查找、删除、插入、替换、遍历

来源:互联网 发布:java怎样输出数组 编辑:程序博客网 时间:2024/05/20 00:13
/*********************************************************************************************************
顺序二叉树的建立、查找、删除、插入、替换、遍历
默认是中序遍历
前序遍历让我注释了,要是用的话取消注释即可
测试的数据第一个输入:8
第二个输入
10
18
3
8
19
2
7
8

******************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
int shu[MAX];
typedef struct play{
    int data;
    struct play *rlink;
    struct play *llink;
}PLAY;
PLAY*insertree(PLAY*tree,int x)//插入一个节点
{
    PLAY *pt,*prept;
    if(tree==NULL)
    {
        pt=(PLAY*)malloc(sizeof(PLAY));
        pt->data=x;
        pt->llink=NULL;
        pt->rlink=NULL;
        tree=pt;
    }
    else
    {
        pt=tree;
        while(pt!=NULL)//一般出现这句话的时候基本是要设一个变量保存pt的前驱结点
        {
            prept=pt;
            if(x<pt->data) pt=pt->llink;
            else pt=pt->rlink;
        }
        pt=(PLAY*)malloc(sizeof(PLAY));
        pt->data=x;
        pt->llink=NULL;
        pt->rlink=NULL;
        if(prept->data>x) prept->llink=pt;
        else prept->rlink=pt;
    }
    return tree;
}
PLAY*build(int n)//建立一个树
{
    PLAY*pt=NULL;
    for(int i=0;i<n;i++) pt=insertree(pt,shu[i]);
    return pt;
}
PLAY*FIND(PLAY*tree,int x)//查找
{
    int flag=0;
    PLAY *prept,*pt;
    pt=tree;
    while(pt!=NULL&&(!flag))
    {
        if(pt->data==x) flag=1;
        else if(x<pt->data) pt=pt->llink;
        else pt=pt->rlink;
    }
    if(flag) prept=pt;
    else prept=NULL;
    return prept;
}
void order(PLAY *tree)//中序法遍历//其实也可以叫堆排序
{
    PLAY*pt;
    PLAY*s[MAX];
    int top;
    top=-1;
    pt=tree;
    do
    {
        while(pt!=NULL)
        {
            s[++top]=pt;
            pt=pt->llink;
        }
        if(top!=-1)
        {
            pt=s[top--];
            printf("%d\n",pt->data);
            pt=pt->rlink;
        }
    }while((pt!=NULL)||(top!=-1));
}


PLAY*FINDF(PLAY*tree,int x)//寻找双亲结点
{
    PLAY*pt,*prept;
    int flag=0;
    pt=tree;
    while(pt!=NULL&&(!flag))
    {
        if(pt->data==x) flag=1;
        else if(x<pt->data) {prept=pt;pt=pt->llink;}
        else {prept=pt;pt=pt->rlink;}
    }
    if(tree->data==x) return NULL;
    return prept;
}
PLAY*detree(PLAY*tree,int x)//删除一个结点有四种形式
{
    PLAY*pt,*prept,*f,*s;
    pt=FIND(tree,x);
    int flag=0;
    if((pt->llink!=NULL)&&(pt->rlink!=NULL))//被删除的结点P有左右子树,则要找出右子树中码值最小的得点s取代p;
    {
        f=FINDF(tree,x);
        prept=pt;
        s=prept->rlink;
        while(s->llink!=NULL)
        {
            prept=s;
            s=s->llink;
        }
        s->llink=pt->llink;
        if(prept!=pt)
        {
            prept->llink=s->rlink;
            s->rlink=pt->rlink;
        }
        if(pt==tree) tree=s;//这个是树顶没有双亲结点
        else flag=1;
        if(flag==1)
        {
            if(pt==f->llink) f->llink=s;
            else f->rlink=s;
        }
    }
    else if((pt->llink==NULL)&&(pt->rlink!=NULL))
    {
        if(pt==tree) tree=pt->rlink;
        else
        {
            f=FINDF(tree,x);
            if(f->llink==pt) f->llink=pt->rlink;
            else f->rlink=pt->rlink;
        }
    }
    else if((pt->llink!=NULL)&&(pt->rlink==NULL))
    {
        if(pt==tree) tree=pt->llink;
        else
        {
            f=FINDF(tree,x);
            if(f->rlink==pt) f->rlink=pt->llink;
            else f->llink=pt->llink;
        }
    }
    else
    {
        if(pt!=tree)
        {
            f=FINDF(tree,x);
            if(f->llink==pt) f->llink=NULL;
            else f->rlink=NULL;
        }
        else pt=NULL;
    }
    free(pt);
    return tree;
}


PLAY*change(PLAY*tree,int x,int y)//替换一个结点把x替换成y
{
    tree=detree(tree,x);
    tree=insertree(tree,y);
    return tree;
}
void preorder(PLAY*t)//前序遍历
{
    PLAY*p;
    PLAY*s[MAX];
    int top=-1;
    p=t;
    do
    {
        while(p!=NULL)
        {
            printf("%d\n",p->data);
            if(p->rlink!=NULL)
                s[++top]=p->rlink;
            p=p->llink;
        }
        if(top!=-1)
        {
            p=s[top--];
        }
    }while((p!=NULL)||(top!=-1));
}


int main()
{
    int n,m;
    printf("请输入建立多长的树:\n");
    while(scanf("%d",&n)!=EOF)
    {
        printf("请输入树的各结点的值:\n");
        for(int i=0;i<n;i++) scanf("%d",&shu[i]);
        PLAY*tree=build(n);
        int choice,y,flag=0;
        while(flag==0)
        {
            printf("请选择:\n1.插入\n2.查找\n3.删除\n4.替换\n5.退出\n");
            scanf("%d",&choice);
            switch(choice)
            {
                case 1:printf("请输入要插入的结点:\n");scanf("%d",&m);tree=insertree(tree,m);break;
                case 2:printf("请输入要查找的结点:\n");scanf("%d",&m);if(FIND(tree,m)!=NULL)printf("yes\n");else printf("NO\n");break;
                case 3:printf("请输入要删除的结点:\n");scanf("%d",&m);tree=detree(tree,m);break;
                case 4:printf("请输入要替换的结点:\n");scanf("%d",&m);printf("请输入替换成哪个数:\n");scanf("%d",&y);tree=change(tree,m,y);break;
                case 5:flag=1;
                default:break;
            }
            printf("经过该操作后的树中序遍历为:\n");
            order(tree);
            //preorder(tree);这个为前序遍历
        }
    return 0;
    }
}
/*
测试数据
8
10
18
3
8
19
2
7
8
*/
阅读全文
1 0