树与二叉树

本文深入探讨了二叉树的基本概念及其遍历方式,包括先序、中序和后序遍历,并介绍了哈夫曼树的生成与哈夫曼编码的原理。通过实例演示,展示了如何利用哈夫曼编码实现数据压缩,以及在实际应用中的重要性。

 树与二叉树

                         按层次遍历二叉树

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 10

typedef struct node

{

    char data;//数据结点

    struct node *lchild,*rchild;

}BSTree;

typedef struct

{

    BSTree *data[MAXSIZE];//队中元素存储空间

    int rear,front;//队尾队头指针

}SeQueue;//顺序栈类型

void Init_SeQueue(SeQueue**q)//循环队列初始化

{

    *q=(SeQueue *)malloc(sizeof(SeQueue));

    (*q)->front=0;

    (*q)->rear=0;

}

int Empty_SeQueue(SeQueue*q)//判队空

{

    if(q->front==q->rear)

    return 1;

    else

    return 0;

}

void In_SeQueue(SeQueue*q,BSTree *x)//元素入队

{

    if((q->rear+1)%MAXSIZE==q->front)

    printf("Queue is full!\n");//队满,入队失败

    else

    {

        q->rear=(q->rear+1)%MAXSIZE;//对尾指针加一

        q->data[q->rear]=x;//将元素x出队

    }

}

void Out_SeQueue(SeQueue*q,BSTree **x)//元素入队

{

    if(q->front==q->rear)

    printf("Queue is empty");//队空出队失败

    else

    {

        q->front=(q->front+1)%MAXSIZE;//对头指针加一

        *x=q->data[q->front];//队头元素出队由x返回队头元素值

    }

}

void Inorder(BSTree *p)//中序遍历

{

    if(p!=NULL)

    {

        Inorder(p->lchild);//中序遍历左子树

        printf("%3c",p->data);//访问根节点

        Inorder(p->rchild);//遍历右子树

    }

}

void Createb(BSTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')

    {

        *p=(BSTree *)malloc(sizeof(BSTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);//沿左孩子分支继续生成二叉树

        Createb(&(*p)->rchild);//沿右孩子分支继续生成二叉树

    }

    else

    *p=NULL;

}

void Transleve(BSTree *t)//层次遍历二叉树

{

    SeQueue *Q;

    BSTree *p;

    Init_SeQueue(&Q);//队列Q初始化

    if(t!=NULL)//二叉树t非空

    printf("%2c",t->data);//输出根节点信息

    In_SeQueue(Q,t);//指针t入队

    while(!Empty_SeQueue(Q))//队列q非空

    {

        Out_SeQueue(Q,&p);//队头结点出队并赋给p

        if(p->lchild!=NULL)//p有左孩子

        {

           printf("%2c",p->lchild->data);//输出右孩子信息

            In_SeQueue(Q,p->lchild);//p右孩子指针入队

        }

        if(p->rchild!=NULL)

        {

            printf("%2c",p->rchild->data);

            In_SeQueue(Q,p->rchild);

        }

    }

}

void main()

{

    BSTree *root;

    printf("Postorder entet bitreewith'..'");

    Createb(&root);//建立一颗以root为根指针的二叉树

    printf("Inorder output:\n");

    Inorder(root);//中序遍历二叉树

    printf("\n");

    Transleve(root);//按层次遍历二叉树

    printf("\n");

}

                       二叉树遍历的应用

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;//左右孩子指针

}BSTree;//二叉树结点类型

void Preorder(BSTree *p)//先序遍历二叉树

{

    if(p!=NULL)

    {

        printf("%3c",p->data);//访问根节点

        Preorder(p->lchild);//先序遍历左子树

        Preorder(p->rchild);//先序遍历右子树

    }

}

BSTree *Search(BSTree *p,charx)//中序遍历查找数据元素

{

    BSTree *stack[MAXSIZE];

    int i=0;

    stack[0]=NULL;//栈初始化

    while(i>=0)//当指针p不空或栈stack不空

    {

        if(p!=NULL)//当指针p不空

        {

            if(p->data==x)

            return p;//查找成功返回p指针值

            else

            stack[++i]=p;//将该节点压站

            p=p->lchild;//沿左子树向下遍历

        }

        else//当指针p为空时

        {

            p=stack[i--];//将这个无左子树的结点由栈弹出

            p=p->rchild;//从该节点右子树的根开始继续沿左子树向下遍历

        }

        if(p==NULL&&i==0)

        break;

    }

    return NULL;//查找失败

}

int Countleaf(BSTree *bt)//统计二叉树中叶子节点的个数

{

    if(bt==NULL)

    return 0;//空二叉树

   if(bt->rchild==NULL&&bt->lchild==NULL)

    return 1;//只有根节点

    return(Countleaf(bt->lchild)+Countleaf(bt->rchild));

}

int Depth(BSTree *p)//求二叉树深度

{

    int lchild,rchild;

    if(p==NULL)

    return 0;//树的深度为0

    else

    {

        lchild=Depth(p->lchild);//求左子树高度

        rchild=Depth(p->rchild);//求右子树高度

        returnlchild>rchild?(lchild+1):(rchild+1);

    }

}

void Createb(BSTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);

    if(ch!='.')

    {

        *p=(BSTree *)malloc(sizeof(BSTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);

        Createb(&(*p)->rchild);

    }

    else

    *p=NULL;

}

void main()

{

    BSTree *root,*p;

    char x;

    printf("Preorder entet bitreewith'..':\n");

    Createb(&root);//建立一颗以root为指针的二叉树

    printf("Preorder output :\n");

    Preorder(root);//先序遍历二叉树

    printf("\n");

    getchar();

    printf("Input element ofSearch:\n");

    scanf("%c",&x);//输入要查找的二叉树结点信息

    p=Search(root,x);//在二叉树中查找结点

    if(p==NULL)

    printf("No found!\n");//二叉树中没有该节点

    else

    printf("Element Searched is%c\n",p->data);//输出找到的结点信息

    printf("leaf of tree is%d\n",Countleaf(root));//输出二叉树的叶子个数

    printf("Deth of tree is%d\n",Depth(root));//输出二叉树的深度

}

                             二叉树的遍历

#include <stdio.h>

#include <stdlib.h>

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;//左右孩子指针

}BSTree;//二叉树结点类型

void Preorder(BSTree *p)//先序遍历

{

    if(p!=NULL)

    {

        printf("%3c",p->data);//访问根节点

        Preorder(p->lchild);//先序遍历左子树

        Preorder(p->rchild);//先序遍历右子树

    }

}

void Inorder(BSTree *p)//中序遍历

{

    if(p!=NULL)

    {

        Inorder(p->lchild);//中序遍历左子树

        printf("%3c",p->data);//中序遍历根节点

        Inorder(p->rchild);//中序遍历右子树

    }

}

void Postorder(BSTree *p)//后序遍历

{

    if(p!=NULL)

    {

        Postorder(p->lchild);//后序遍历左子树

        Postorder(p->rchild);//后序遍历右子树

        printf("%3c",p->data);//后序遍历根节点

    }

}

void Createb(BSTree **p)//生成一个二叉树

{

    char ch;

    scanf("%c",&ch);//输入第一个字符

    if(ch!='.')//如果该字符不为“.”

    {

        *p=(BSTree *)malloc(sizeof(BSTree));//在主调函数空间申请一个节点

        (*p)->data=ch;//将读入的字符送结点数据域

        Createb(&(*p)->lchild);//沿左孩子分支继续生成二叉树

        Createb(&(*p)->rchild);//沿右孩子分支继续生成二叉树

    }

    else//如果读入的字符为“."

     *p=NULL;

}

void main()

{

    BSTree *root;

    printf("Preorder enten bitree with '..':\n");

    Createb(&root);//建立一颗以root为根指针的二叉树

    printf("Preorder output :\n");

    Preorder(root);//先序遍历二叉树

    printf("\n");

    printf("Inorder output :\n");

    Inorder(root);//中序遍历二叉树

    printf("\n");

    printf("Postorder output :\n");

    Postorder(root);//后序遍历二叉树

    printf("\n");

}

                          二叉树的非递归遍历

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;

}BSTree;

void Preorder(BSTree *p)//先序遍历二叉树

{

    BSTree *stack[MAXSIZE];

    int i=0;

    stack[0]=NULL;//栈初始化

    while(p!=NULL||i>0)//当指针p不空或栈stack不为空

    if(p!=NULL)//当指针p不为空

    {

        printf("%3c",p->data);//输出结点信息

        stack[++i]=p;//将结点压入栈

        p=p->lchild;//沿左子树向下遍历

    }

    else//当指针p为空时

    {

        p=stack[i--];//将这个无左子树的结点由栈弹出

        p=p->rchild;//从该结点右子树的根节点开始继续沿左子树向下遍历

    }

}

void Inorder(BSTree *p)//中序遍历

{

    BSTree *stack[MAXSIZE];

    int i=0;

    stack[0]=NULL;//栈初始化

    while(i>=0)//当指针p】不为空或stack不为空

    {

        if(p!=NULL)//当指针p不为空时

        {

            stack[++i]=p;//将该节点压栈

            p=p->lchild;//沿左子树向下遍历

        }

        else//当指针 p为空时

        {

            p=stack[i--];//将这个无左子树的结点由栈弹出

           printf("%3c",p->data);//输出结点信息

            p=p->rchild;//从该节点右子树的根开始继续沿左子树向下遍历

        }

        if(p==NULL&&i==0)//指针p为空且栈stack也为空则二叉树遍历结束

        break;

    }

}

void Postorder(BSTree *p)//后序遍历

{

    BSTree *stack[MAXSIZE];

    int b[MAXSIZE],i=0;//数组b用于标识每个结点是否已遍历过期左右子树

    stack[0]=NULL;//栈初始化

    do

    {

        if(p!=NULL)//当指针p不为空时

        {

            stack[++i]=p;//将遍历中遇到的所有结点依次压站

            b[i]=0;//置该节点右子树未访问过的标志

            p=p->lchild;//沿该节点左子树继续向下遍历

        }

        else

        {

            p=stack[i--];//将这个无左子树的当前结点由栈弹出

            if(!b[i+1])//b[i+1]为0,则当前结点的右子树未遍历

            {

                stack[++i]=p;//将当前结点重新压栈

                b[i]=1;//置当前结点右子树已访问过标志

                p=p->rchild;//沿当前结点右孩子继续向下遍历

            }

            else//当前结点的左右子树都已遍历

            {

               printf("%3c",p->data);//输出当前结点信息

                p=NULL;//将指向当前结点的指针置空

            }

        }

    }while(p!=NULL||i>0);//当指针p不为空或栈stack不为空时继续遍历

}

void Createb(BSTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')//如果不为'.'

    {

        *p=(BSTree *)malloc(sizeof(BSTree));//在主调函数空间申请一个节点

        (*p)->data=ch;//将读入字符送结点的数据域

        Createb(&(*p)->lchild);//沿左孩子结点继续生成二叉树

        Createb(&(*p)->rchild);//沿右孩子分支继续生成二叉树

    }

    else//如果读入的字符为'.',则置指针域为空

    *p=NULL;

}

void main()

{

    BSTree *root;

    printf("Preorder entet bitreewith'..':\n");

    Createb(&root);

    printf("Preorder output :\n");

    Preorder(root);

    printf("\n");

    printf("Inorder output :\n");

    Inorder(root);

    printf("\n");

    printf("Postorder output :\n");

    Postorder(root);

    printf("\n");

}

                   哈夫曼树及哈夫曼编码

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 40

#define MAXBIT 10//定义哈夫曼编码的最大长度

typedef struct

{

    int weight,parent,lchild,rchild;

}HNode;//哈夫曼树结点类型

typedef struct

{

    int weight;

    int bit[MAXBIT];

    int start;

}HCode;//哈夫曼编码类型

void HuffTree(HNodeHuff[],int n)//生成哈夫曼树

{

    int i,j,m1,m2,x1,x2;

    for(i=0;i<2*n-1;i++)//数组初始化

    {

        Huff[i].weight=0;

        Huff[i].parent=-1;

        Huff[i].lchild=-1;

        Huff[i].rchild=-1;

    }

    printf("Input 1~n value ofleaf:\n");

    for(i=0;i<n;i++)//输入n个叶子节点的权值

    scanf("%d",&Huff[i].weight);

    for(i=0;i<n-1;i++)//构造哈弗曼树并生成该树的n-1个分支结点

    {

        m1=m2=32767;

        x1=x2=0;

        for(j=0;j<n+i;j++)

        {//选取最小和次小两个权值结点并将其序号送x1和x2

           if(Huff[j].parent==-1&&Huff[j].weight<m1)

            {

                m2=m1;

                x2=x1;

                m1=Huff[j].weight;

                x1=j;

            }

            else

            if(Huff[j].parent==-1&&Huff[j].weight<m2)

            {

                m2=Huff[j].weight;

                x2=j;

            }

        }//将找出的两棵树合并为一颗新的子树

        Huff[x1].parent=n+i;//将两颗子树根节点的双亲结点序号为n+1

        Huff[x2].parent=n+i;

       Huff[n+i].weight=Huff[x1].weight+Huff[x2].weight;//新子树根节点的权值为两颗子树根节点权值之和

        Huff[n+i].lchild=x1;

        Huff[n+i].rchild=x2;

    }

    printf("Huff  weight  lchid    rchild    prent\n");

    for(i=0;i<2*n-1;i++)//输出哈夫曼树

    printf("%3d%5d%10d%10d%10d\n",i,Huff[i].weight,Huff[i].lchild,Huff[i].rchild,Huff[i].parent);

}

void HuffmanCode()//生成哈夫曼编码

{

    HNode HuffNode[MAXSIZE];//MAXSIZE为二叉树所有结点的最大个数

    HCode HuffCode[MAXSIZE/2],cd;//MAXSIZE/2为叶结点的最大个数

    int i,j,c,p,n;

    printf("Input numbers ofleaf:\n");//n为叶结点个数

    scanf("%d",&n);

    HuffTree(HuffNode,n);//建立哈夫曼树

    for(i=0;i<n;i++)//求每个结点的哈夫曼编码

    {

       HuffCode[i].weight=HuffNode[i].weight;//保存叶结点的权值

        cd.start=MAXBIT-1;//存放分支编码从数组bit最后一个元素位置开始向前进行

        c=i;//c为结点在数组HuffNod中的序号

        p=HuffNode[c].parent;

        while(p!=-1)//从叶结点开始沿双亲链直到根节点,根节点的双亲值为-1

        {

            if(HuffNode[p].lchild==c)//双亲的左孩子序号为c

            cd.bit[cd.start]=0;//该分支编码为0

            else

            cd.bit[cd.start]=1;//该分支编码为1

            cd.start--;//前移一个位置准备存放下一个分支编码

            c=p;//c移至其双亲结点序号

            p=HuffNode[c].parent;//p再定位于c的双亲结点序号

        }

        for(j=cd.start+1;j<MAXBIT;j++)//保存该叶结点字符的哈夫曼编码

        HuffCode[i].bit[j]=cd.bit[j];

        HuffCode[i].start=cd.start;//保存该编码在数组bit中的起始位置

    }

    printf("HuffCode  weight  bit \n");//输出数组HuffCode的有关信息

    for(i=0;i<n;i++)//输出各叶结点对应的哈夫曼编码

    {

        printf("%5d%8d      ",i,HuffCode[i].weight);

        for(j=HuffCode[i].start+1;j<MAXBIT;j++)

       printf("%d",HuffCode[i].bit[j]);

        printf("\n");

    }

}

void main()

{

    HuffmanCode();//生成哈夫曼编码

}

                           另一种后序非递归遍历二叉树

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;

}BSTree;

void Postorder(BSTree *p)//后序遍历二叉树

{

    BSTree *stack[MAXSIZE],*q;

    int b,i=-1;

    do

    {

        while(p!=NULL)//将*p结点左分支上的所有孩子入栈

        {

            stack[++i]=p;

            p=p->lchild;

        }//栈顶结点已没有左孩子或左子树的结点都已经访问过

        q=NULL;

        b=1;//置已访问过的标记

        while(i>=0&&b)//栈stack不空且当前栈顶结点的左子树已经遍历过

        {

            p=stack[i];//取出当前栈顶结点

            if(p->rchild==q)//当前栈顶结点*p无右孩子或*p的右孩子已经访问过

            {

                printf("%3c",p->data);//输出当前栈顶结点*p的信息

                i--;

                q=p;//q指向刚访问过的结点p

            }

            else//当前栈顶结点*p有右子树

            {

                p=p->rchild;//p指向当前栈顶结点*p的右孩子结点

                b=0;//置该右孩子结点未遍历过其右子树标记

            }

        }

    }while(i>=0);//当栈stack非空时继续遍历

}

void Createb(BSTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')//如果该字符不为'.'

    {

        *p=(BSTree *)malloc(sizeof(BSTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);//沿左孩子分支继续生成二叉树

        Createb(&(*p)->rchild);//沿右孩子分支继续生成二叉树

    }

    else

    *p=NULL;

}

void main()

{

    BSTree *root;

    printf("Make a tree :\n");

    Createb(&root);

    printf("Postorder output :\n");

    Postorder(root);

    printf("\n");

}

                             由二叉树的遍历序列恢复二叉树

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;//左右孩子结点

}BSTree;//二叉树结点类型

charpred[MAXSIZE],ind[MAXSIZE];

int i=0,j=0;

void Preorder(BSTree *p)//先序遍历二叉树

{

    if(p!=NULL)

    {

        pred[i++]=p->data;//保存根节点数据

        Preorder(p->lchild);//先序遍历左子树

        Preorder(p->rchild);//先序遍历右子树

    }

}

void Inorder(BSTree *p)//中序遍历二叉树

{

    if(p!=NULL)

    {

        Inorder(p->lchild);//中序遍历左子树

        ind[j++]=p->data;//保存根节点数据

        Inorder(p->rchild);//中序遍历右子树

    }

}

void Pre_In_order(charpred[],char ind[],int i,int j,int k,int h,BSTree **p)

{//i、j、k、h分别为当前先序序列、中序序列的上下界

    int m;

    *p=(BSTree *)malloc(sizeof(BSTree));

    (*p)->data=pred[i];//根据pred数组生成二叉树的根结点

    m=k;//m指向ind数组所存储的中序序列中第一个结点

    while(ind[m]!=pred[i])

    m++;

    if(m==k)//若根节点时中序序列的第一个结点,则无左子树

    (*p)->lchild=NULL;

    else

   Pre_In_order(pred,ind,i+1,i+m-k,k,m-1,&(*p)->lchild);//根据结点所划分出中序序列的两部分继续构成左、右两颗子树

    if(m==h)//若根节点时中序序列的最后一个结点,则无右子树

    (*p)->rchild=NULL;

    else

   Pre_In_order(pred,ind,i+m-k+1,j,m+1,h,&(*p)->rchild);//根据结点所划分出中序序列的两部分继续构造左右两颗子树

}

void Print_Inorder(BSTree*p)//中序遍历二叉树

{

    if(p!=NULL)

    {

        Print_Inorder(p->lchild);

        printf("%3c",p->data);

        Print_Inorder(p->rchild);

    }

}

void Createb(BSTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')

    {

        *p=(BSTree *)malloc(sizeof(BSTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);//沿左孩子继续生成二叉树

        Createb(&(*p)->rchild);//沿右孩子继续生成二叉树

    }

    else

    *p=NULL;

}

void main()

{

    BSTree *root,*root1;

    printf("Preorder entet bitree with'..':\n");

    Createb(&root);//建立一颗以root为根指针的二叉树

    printf("Inorder outputroot:\n");//输出建立的二叉树

    Print_Inorder(root);

    printf("\n");

    Preorder(root);//先序遍历二叉树生成pred数组

    printf("Inorder output :\n");

    Inorder(root);//中序遍历二叉树生成ind数组

    if(i>0)//根据数组pred和ind保存的遍历序列恢复二叉树

    Pre_In_order(pred,ind,0,i-1,0,j-1,&root1);

    printf("Inorder outputroot1:\n");//输出恢复后的二叉树

    Print_Inorder(root1);

    printf("\n");

}

                          中序线索二叉树

#include <stdio.h>

#include <stdlib.h>

typedef struct node

{

    char data;//结点数据

    int ltag,rtag;//线索标记

    struct node *lchild;//左孩子或直接前驱线索指针

    struct node *rchild;//右孩子或直接后继线索指针

}TBTree;//线索二叉树结点类型

TBTree *pre;//全局变量

void Thread(TBTree *p)//对二叉树进行中序线索化

{

    if(p!=NULL)

    {

        Thread(p->lchild);//先对p的左子树线索化

        if(p->lchild==NULL)//p的左孩子不存在或已经线索化,对p进行线索化

        {

            p->lchild=pre;//建立p的前驱线索

            p->ltag=1;

        }

        else

        p->ltag=0;//置p的lchild指针为指向左孩子的标志

        if(pre->rchild==NULL)//pre的右孩子不存在则进行后继线索

        {

            pre->rchild=p;//建立pre的后继线索

            pre->rtag=1;

        }

        else

        pre->rtag=0;//置p的rchild指针为指向哟孩子标志

        pre=p;//pre移至p结点

        Thread(p->rchild);//对p的右子树线索化

    }

}

TBTree *CreaThread(TBTree*b)//建立中序线索二叉树

{

    TBTree *root;

    root=(TBTree *)malloc(sizeof(TBTree));//创建头结点

    root->ltag=0;

    root->rtag=1;

    if(b==NULL)//二叉树为空

    root->lchild=root;

    else

    {

        root->lchild=b;//root的lchild指针指向二叉树根节点b

        pre=root;//pre是p的前驱结点,pre指针用于线索

        Thread(b);//对二叉树b进行中须线索花

        pre->rchild=root;//最后处理,加入指向头结点的线索

        pre->rtag=1;

        root->rchild=pre;//头结点的rchild指针线索化为指向最后一个结点

    }

    return root;//返回线索化后指向二叉树头结点的指针

}

void Inorder(TBTree *b)//中序遍历中序线索二叉树

{

    TBTree *p;

    p=b->lchild;//p指向根节点

    while(p!=b)//当p不等于指向头结点的指针b时

    {

        while(p->ltag==0)//寻找中序序列的第一个结点

        p=p->lchild;

        printf("%3c",p->data);//输出中序序列的第一个结点数据

       while(p->rtag==1&&p->rchild!=b)//后继线索存在且后继线索不为头结点时

        {

            p=p->rchild;//根据后继线索找到后继结点

           printf("%3c",p->data);//输出后继结点信息

        }

        p=p->rchild;//无后继线索则p指向右孩子结点

    }

}

void Preorder(TBTree *p)//先序遍历

{

    if(p!=NULL)

    {

        printf("%3c",p->data);

        Preorder(p->lchild);

        Preorder(p->rchild);

    }

}

void Createb(TBTree **p)//生成一颗二叉树

{

    char ch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')

    {

        *p=(TBTree *)malloc(sizeof(TBTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);

        Createb(&(*p)->rchild);

    }

    else

    *p=NULL;

}

void main()

{

    TBTree *root,*p;

    printf("Preorder entet bitreewith'..':\n");

    Createb(&root);

    printf("Preorder output :\n");

    Preorder(root);

    printf("\n");

    p=CreaThread(root);

    printf("Inorder output :\n");

    Inorder(p);

    printf("\n");

}

                               左右子树交换

/*二叉树以二叉链表为存储结构,试设计一个算法,若结点左孩子的data值大于右孩子,则交换左右子树*/

#include <stdio.h>

#include <stdlib.h>

#define MAXSIZE 30

typedef struct node

{

    char data;//结点数据

    struct node *lchild,*rchild;//左右孩子指针

}BSTree;

void Inorder(BSTree *p)//中序遍历

{

    if(p!=NULL)

    {

        Inorder(p->lchild);

        printf("%3c",p->data);

        Inorder(p->rchild);

    }

}

void Change(BSTree *p)//左右孩子交换

{

    BSTree *q;

    if(p!=NULL)

    {

       if(p->lchild!=NULL&&p->rchild!=NULL&&p->lchild->data>p->rchild->data)

        {//交换左右孩子指针

            q=p->lchild;

            p->lchild=p->rchild;

            p->rchild=q;

        }

        Change(p->lchild);

        Change(p->rchild);

    }

}

void Createb(BSTree **p)//生成一颗二叉树

{

    charch;

    scanf("%c",&ch);//读入一个字符

    if(ch!='.')

    {

        *p=(BSTree *)malloc(sizeof(BSTree));

        (*p)->data=ch;

        Createb(&(*p)->lchild);

        Createb(&(*p)->rchild);

    }

    else

    *p=NULL;

}

void main()

{

    BSTree *root;

    printf("Make a tree:\n");

    Createb(&root);

    printf("Inorder output :\n");

    Inorder(root);

    printf("\n");

    Change(root);

    printf("Inorder output ofchange:\n");

    Inorder(root);

    printf("\n");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值