二叉树基本操作的程序实现

来源:互联网 发布:mac版qq群文件 编辑:程序博客网 时间:2024/05/01 16:04

//Bintree.h
#include<stdio.h>
#include<malloc.h>
typedef struct Binnode{//二叉树结点结构体
    char data;
    struct Binnode *lchild;
    struct Binnode *rchild;
  };
typedef Binnode *Bintree ;

typedef struct stack{ //二叉树结点栈
     Bintree data[100];
    int flag[100];
    int top;
  };

typedef struct queue{ //二叉树结点队列
    Bintree data[30];
    int front;
    int rear;
  };


  
/*******************************************/
/*          按照前序遍历建立二叉树         */
/*******************************************/

void Creat_Bintree(Bintree *root)
{
    char ch;
    if((ch=getchar())==' ')
    {
        *root=NULL;

    }
    else
    {
        *root=(Binnode*)malloc(sizeof(Binnode));
        (*root)->data=ch;
        Creat_Bintree(&(*root)->lchild);
        Creat_Bintree(&(*root)->rchild);
    }
}

/*******************************************/
/*          按照前序递归遍历二叉树         */
/*******************************************/

void Preorder1(Bintree t)
{
    if(t!=NULL)
    {
        printf("%c",t->data);
        Preorder1(t->lchild);
        Preorder1(t->rchild);
    }
}


/*******************************************/
/*          按照中序递归遍历二叉树         */
/*******************************************/

void Inorder1(Bintree t)
{
    if(t!=NULL)
    {
        Inorder1(t->lchild);
        printf("%c",t->data);
        Inorder1(t->rchild);
    }
}

/*******************************************/
/*          按照后序递归遍历二叉树         */
/*******************************************/

void Posorder1(Bintree t)
{
    if(t!=NULL)
    {
        Posorder1(t->lchild);
        Posorder1(t->rchild);
        printf("%c",t->data);
    }
}
/*******************************************/
/*          按照前序非递归遍历二叉树         */
/*******************************************/

void Preorder2(Bintree t)
{
    Bintree pre=t;
    stack s;
    s.top=0;
    printf("输出前序遍历序列:");
    while(pre||s.top>0)
    {
        if(pre)
        {
            printf("%c",pre->data);
            s.data[s.top++]=pre;
            pre=pre->lchild;
        }
        else
        {
            pre=s.data[--s.top]->rchild;
        }
    }
    printf("\n\n");
}

/*******************************************/
/*          按照中序非递归遍历二叉树         */
/*******************************************/

void Inorder2(Bintree t)
{
    Bintree pre=t;
    stack s;
    s.top=0;
     printf("输出中序遍历序列:");
    while(pre||s.top>0)
    {
        if(pre)
        {
            s.data[s.top++]=pre;
            pre=pre->lchild;
        }
        else
        {
            pre=s.data[--s.top];
            printf("%c",pre->data);
            pre=pre->rchild;
        }
    }
    printf("\n\n");
}

/*******************************************/
/*        按照后序非递归遍历二叉树         */
/*******************************************/

void Posorder2(Bintree t)
{
    stack s;
    s.top=-1;
    printf("输出后序遍历序列:");
    while(t!=NULL||s.top!=-1)
    {
        while(t)
        {
            s.top++;
            s.flag[s.top]=0;
            s.data[s.top]=t;
            t=t->lchild;
           
        }
        while(s.top>=0&&s.flag[s.top]==1)
        {
            t=s.data[s.top];
            printf("%c",t->data);
            s.top--;
        }
        if(s.top>=0)
        {
            t=s.data[s.top];
            s.flag[s.top]=1;
            t=t->rchild;
        }
        else
        {
            t=NULL;
        }
    }
    printf("\n\n");
}


/*******************************************/
/*           按照层次遍历二叉树            */
/*******************************************/
void Levelorder(Bintree t)
{
    queue q;
    q.data[0]=t;
    q.front=0;q.rear=1;
    printf("层次遍历二叉树结果:");
    while(q.front<q.rear)
    {
        if(q.data[q.front])
        {
            printf("%c",q.data[q.front]->data);
            q.data[q.rear++]=q.data[q.front]->lchild;
            q.data[q.rear++]=q.data[q.front]->rchild;
            q.front++;
        }
        else
        {
            q.front++;
        }
    }
    printf("\n\n");
}

#include"Bintree.h"
/*******************************************/
/*      递归法将二叉树的左右子树互换       */
/*******************************************/
void Exchange1(Bintree t)
{
    Bintree temp;
    if(t)
    {
        Exchange1(t->lchild);
        Exchange1(t->rchild);
        temp=t->lchild;
        t->lchild=t->rchild;
        t->rchild=temp;
    }
}
/*******************************************/
/*      非递归法将二叉树的左右子树互换     */
/*******************************************/
void Exchange2(Bintree t)
{
    Bintree temp;
    stack s;
    s.top=0;
    while(t||s.top)
    {
        if(t)
        {
            s.data[s.top++]=t;
            temp=t->lchild;
            t->lchild=t->rchild;
            t->rchild=temp;
            t=t->lchild;
        }
        else
        {
            t=s.data[--s.top]->rchild;
        }

    }
}
int main()
{
    Bintree t;
    Creat_Bintree(&t);
    Exchange2(t);
    Inorder2(t);
    return 0;
}

#include"Bintree.h"
/*******************************************/
/*        递归法求叶子结点个数             */
/*******************************************/
int Leaves_Num1(Bintree t)
{
    if(t)
    {
        if(t->lchild==NULL&&t->rchild==NULL)
        {
            return 1;
        }
        return Leaves_Num1(t->lchild)+Leaves_Num1(t->rchild);
    }
    return 0;
}

/*******************************************/
/*        非递归法求叶子结点个数             */
/*******************************************/
int Leaves_Num2(Bintree t)
{
    int count=0;
    stack s;
    s.top=0;
    while(t||s.top>0)
    {
        if(t)
        {
             s.data[s.top++]=t;
             if(t->lchild==NULL&&t->rchild==NULL)
             {

                count++;
             }
             t=t->lchild;
        }
        else
        {
            t=s.data[--s.top]->rchild;
        }
    }
    return count;
}

        
int main()
{
    int count=0;
    Bintree t;
    Creat_Bintree(&t);
    count=Leaves_Num2(t);
    printf("该二叉树的叶子结点数为:%d\n",count);
    return 0;
}

#include"Bintree.h"

/**********************************************/
/*                  求一棵树的高度            */
/**********************************************/

int Depth(Bintree t)
{
    int  lh , rh ;
    if( NULL == t )
    {
        return 0 ;
    }
    else
    {
        lh = Depth( t->lchild ) ;
        rh = Depth( t->rchild ) ;
        return ( lh > rh ? lh : rh ) + 1 ;
    }
}

int main()
{
    Bintree t ;
    Creat_Bintree( &t ) ;
    printf( "树的高度是%d\n" , Depth( t ) ) ;
    return 0 ;
}

#include"Bintree.h"
/*******************************************************/
/*      已知一课棵二叉树的中序和后序,建立这棵树       */
/*******************************************************/

void In_Pos_order(Bintree *t,char *s,char *r)
{
    char La[30],Lb[30],Ra[30],Rb[30];
    int i,len,length=strlen(r);
    if(length>0&&r[length-1]!='\0')
    {
        *t=(Binnode *)malloc(sizeof(Binnode));
        (*t)->data=r[length-1];
        for(i=0;s[i]!=r[length-1];i++)
        {
            Ra[i]=s[i];
            La[i]=r[i];
        }
        len=i;
        Ra[len]='\0'; //左中
        La[len]='\0'; //左后
        for(i=len+1;i<strlen(s);i++)
        {
            Rb[i-len-1]=s[i];
        }
        Rb[i-len-1]='\0';
        for(i=len;i<strlen(r)-1;i++)
        {
            Lb[i-len]=r[i];
        }
        Lb[i-len]='\0';
        In_Pos_order(&(*t)->lchild,Ra,La);
        In_Pos_order(&(*t)->rchild,Rb,Lb);
    }
    else
    {
        *t=NULL;
    }
}

int main()
{
    Bintree t;
    char in[30]="ABCEFGHD",pos[30]="ABFHGEDC";//测试数据
    printf("输入中序遍历序列:");
    scanf("%s",in);
    printf("输入后序遍历序列:");
    scanf("%s",in);
    In_Pos_order(&t,in,pos);
    Preorder2(t);
}

#include"Bintree.h"
/*******************************************************/
/*                  判断两棵是否等价                   */
/*******************************************************/

int Is_equal( Bintree t1 , Bintree t2 )
{
    int t=0;
    if(NULL == t1 && NULL == t2)
    {
        t=1;
    }
    else
    {
        if(NULL !=t1 &&NULL != t2 )
        {
            if(t1->data == t2->data)
            {
                if(Is_equal(t1->lchild,t2->lchild))
                {
                    t=Is_equal(t1->rchild,t2->rchild);
                }
            }
        }
    }
    return t;
}
int main()
{
    Bintree t1,t2;
    Creat_Bintree(&t1);
    getchar();
    Creat_Bintree(&t2);
    if(Is_equal(t1,t2))
    {
         printf( "Yes!\n") ;
    }
    else
    {
        printf( "No!\n" ) ;
    }
    
    return 0 ;
}

#include"Bintree.h"
/****************************************************/
/*            查找某个信息是否在这棵树中            */
/****************************************************/

Bintree locale_x(Bintree t,char x)
{
    Bintree p;
    if(t==NULL) return NULL;
    else
    {
        if( t -> data == x ) return t;
        else
        {
            p = locale_x(t->lchild,x);
            if(p)return p;
            else
            return locale_x(t->rchild,x);
        }
    }
}

int main()
{
    Bintree root,p;
    char ch;
    Creat_Bintree(&root);
    getchar();
    printf("输入要查找的值:");
    scanf("%c",&ch);
    p=locale_x(root,ch);
    if(p)printf( "YES!\n" ) ;
    else printf( "NO!\n" ) ;
    return 0;
}

#include"Bintree.h"

/****************************************************/
/*                  树的结点个数                    */
/****************************************************/
int  num_of_node(Bintree t)
{
    if(t==NULL)return 0 ;
    else return num_of_node(t->lchild)+num_of_node(t->rchild)+1;
}


int main()
{
    Bintree root,p;
    Creat_Bintree(&root);
    printf("%d\n",num_of_node(root));
    return 0;
}

#include"Bintree.h"

/*******************************************************/
/*     已知一课棵二叉树的中序和前序序列,建立这棵树    */
/*******************************************************/

void Pre_In_order(Bintree *t,char *s,char *r)
{
    char La[30],Lb[30],Ra[30],Rb[30];
    int i,len;
    if(s[0]!='\0')
    {
        *t=(Binnode *)malloc(sizeof(Binnode));
        (*t)->data=s[0];
        for(i=0;r[i]!=s[0];i++)
        {
            Ra[i]=r[i];
        }
        len=i;
        Ra[len]='\0'; //左中
        for(i=0;i<len;i++)
        {
            La[i]=s[i+1];
        }
        La[len]='\0'; //左前
        for(i=len+1;i<strlen(r);i++)
        {
            Rb[i-len-1]=r[i];
        }
        Rb[i-len-1]='\0';
        for(i=len+1;i<strlen(s);i++)
        {
            Lb[i-len-1]=s[i];
        }
        Lb[i-len-1]='\0';
        Pre_In_order(&(*t)->lchild,La,Ra);
        Pre_In_order(&(*t)->rchild,Lb,Rb);
    }
    else
    {
        *t=NULL;
    }
}

int main()
{
    Bintree t;
    char pre[30]="ABCDEF",in[30]="CBAEDF";//测试数据
    printf("输入前序遍历序列:");
    scanf("%s",pre);
    printf("输入中序遍历序列:");
    scanf("%s",in);
    Pre_In_order(&t,pre,in);
    Posorder1(t);
}

#include<stdio.h>
#include<malloc.h>
typedef struct node{
    int data;
    struct node *lchild,*rchild,*next;
  }hufnode;

typedef hufnode *linkhuf;
/****************************************************/
/*                      huffman树                   */
/****************************************************/
linkhuf Creat_Node(int n) //创建一单链表
{
    linkhuf head,pre,p;
    int x;
    head=NULL;
    while(n--)
    {
        scanf("%d",&x);
        p=(linkhuf)malloc(sizeof(hufnode));
        p->data=x;
        p->lchild=NULL;
        p->rchild=NULL;
        if(NULL==head)
        {
            head=p;
            pre=head;
        }
        else
        {
            p->next=pre->next;
            pre->next=p;
            pre=pre->next;
        }
    }
    return head;
}
linkhuf insert(linkhuf root , linkhuf s)//将结点S插入到有序Huffman root中。
{
    linkhuf p1,p2;
    if(NULL == root ) root=s;
    else
    {
        p1=NULL;
        p2=root;
        while(p2&&p2->data<s->data)
        {
            p1=p2;
            p2=p2->next;
        }
        s->next=p2;
        if(NULL==p1)
        {
            root=s;
        }
        else
        {
            p1->next=s;
        }
    }
    return root;
}


void Preorder1(linkhuf t)
{
    if(t!=NULL)
    {
        printf("%-6d",t->data);
        Preorder1(t->lchild);
        Preorder1(t->rchild);
    }
}
void creathuffman(linkhuf *root)//构造Huffman树。
{
    linkhuf s, rl,rr;
    while(*root && (*root)->next)
    {
        rl=*root;
        rr=(*root)->next;
        *root=rr->next;
        s=(linkhuf)malloc(sizeof(hufnode));
        s->next=NULL;
        s->data=rl->data+rr->data;
        s->lchild=rl;
        s->rchild=rr;
        rl->next=rr->next=NULL;
        *root=insert(*root,s);
    }
}

int main()
{
    linkhuf root;
    int n;
    scanf("%d",&n);
    root=Creat_Node(n);
    creathuffman(&root);
    Preorder1(root);
    printf("\n");
    return 0;
}

/************************************************************/
/*                  按层次顺序建立一棵二叉树                */
/************************************************************/
#include"Bintree.h"

Bintree Level_Creat()
{
    Bintree root,p,s;
    queue node;
    node.front=node.rear=0;
    char ch;
    ch=getchar();
    if(ch==' ')
    {
        return NULL;
    }
    root=(Binnode*)malloc(sizeof(Binnode)); //生成根结点
    root->data=ch;
    node.data[node.rear++]=root; //用队列实现层次遍历
    while(node.front<node.rear)
    {
        p=node.data[node.front++];
        ch=getchar(); //为了简化操作,分别对左右子结点进行赋值。
        if(ch!=' ')//子树不空则进队列进行扩充。下同
        {
            s=(Binnode*)malloc(sizeof(Binnode));
            s->data=ch;
            p->lchild=s;
            node.data[node.rear++]=s;
        }
        else
        {
            p->lchild=NULL;
        }
        ch=getchar();
        if(ch!=' ')
        {
            s=(Binnode*)malloc(sizeof(Binnode));
            s->data=ch;
            p->rchild=s;
            node.data[node.rear++]=s;
        }
        else
        {
            p->rchild=NULL;
        }
    }
    return root;
}
int main()
{
    Bintree root;
    root=Level_Creat();
    Inorder1(root);//测试,中序遍历
    return 0;
}

//中序穿线二叉树.
#include<stdio.h>
#include<malloc.h>

typedef struct Binnode {
    char data;
    int lflag,rflag;//左右标记
    /*
        lflag=0 表示结点的左指针指向其左子女。
        lflag=1 表示结点的左指针指向其中序遍历的前驱。
        rflag=0 表示结点的左指针指向其右子女。
        rflag=1 表示结点的左指针指向其中序遍历的前驱。
    */
    struct Binnode *lchild,*rchild;
   };
typedef Binnode* Bintree;

Bintree pre=NULL; //初始化前驱结点

/*******************************************/
/*          按照前序遍历建立二叉树         */
/*******************************************/

void Creat_Bintree(Bintree *root)
{
    char ch;
    if((ch=getchar())==' ')
    {
        *root=NULL;

    }
    else
    {
        *root=(Binnode*)malloc(sizeof(Binnode));
        (*root)->data=ch;
        Creat_Bintree(&(*root)->lchild);
        Creat_Bintree(&(*root)->rchild);
    }
}

/*******************************************/
/*          对二叉树进行中序穿线           */
/*******************************************/
void Inthreading(Bintree *t)
{
    if(*t)
    {
        Inthreading(&(*t)->lchild);// 中序线索化左子树
        (*t)->lflag=((*t)->lchild)?0:1;//对当前结点及其前驱结点进行穿线
        (*t)->rflag=((*t)->rchild)?0:1;
        if(pre)
        {
            if((*t)->lflag==1) (*t)->lchild=pre;
            if(pre->rflag==1) pre->rchild=*t;
        }
        pre=*t;
        Inthreading(&(*t)->rchild);// 中序线索化右子树
    }
}

/*******************************************/
/*          中序遍历穿线二叉树             */
/*******************************************/

Bintree Insuccnode(Bintree p) //寻找结点P在中序遍历下的后继结点
{
    Bintree q;
    if(p->rflag==1)//P的右指针为线索,恰巧指向P的后继结点
    {
        return p->rchild;
    }
    else           //寻找P的右子树中最左下的结点
    {
        q=p->rchild;
        while(q->lflag==0)
        {
            q=q->lchild;
        }
        return q;
    }
}

/********************************************************/
/*             中序遍历中序穿线二叉树                   */
/********************************************************/


void Inthrtree(Bintree p)
{
    if(p)
    {
        while(p->lflag==0) //求P中序遍历下的第一个结点
        {
            p=p->lchild;
        }
        do
        {
            printf("%-3c",p->data);
            p=Insuccnode(p); //求P中序遍历下的后继结点
        }
        while(p);
    }
}


int main()
{
    Bintree t;
    Creat_Bintree(&t);
    Inthreading(&t);
    Inthrtree(t);
    printf("\n\n");
    return 0;
}

0 0