王道数据结构习题代码5.3.3(树与二叉树)

第三题(二叉树非递归后序遍历)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;

typedef struct Stack
{

    BiTree data[MaxSize];
    int top;
} SqStack;

void InitStack(SqStack *S)
{
    S->top=-1;
}

bool Push(SqStack *S,BiTree T)
{
    if(S->top==MaxSize-1)return false;
    S->data[++S->top]=T;
    return true;
}


bool Pop(SqStack *S,BiTree *T)
{
    if(S->top==-1)return false;
    *T=S->data[S->top--];
    return true;
}

bool IsEmpty(SqStack *S){
    if(S->top==-1)return true;
    return false;
}

bool GetTop(SqStack *S,BiTree *T)
{
    if(S->top==-1)return false;
    *T=S->data[S->top];
    return true;
}


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}
void visit(BiTree T)
{
    printf("%d ",T->data);
}



void PostOrder(BiTree T)
{
    SqStack S;
    InitStack(&S);
    BiTree p=T,r=NULL;
    while(p||!IsEmpty(&S))
    {
         if(p)
         {
             Push(&S,p);
             p=p->lchild;
         }else{
            GetTop(&S,&p);
            if(p->rchild&&p->rchild!=r)p=p->rchild;//p右孩子!=r 防止重复访问
            else{
                Pop(&S,&p);
                visit(p);
                r=p;
                p=NULL;
            }
         }
    }
}





int main()
{
    printf("请输入首结点: \n");
    BiTree T=CreateLink();
    PostOrder(T);



    return 0;
}



第四题(层次遍历的逆转)

只要关于逆转并且与队列相关,一定想到用栈来辅助实现逆转

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;

typedef struct Stack
{

    BiTree data[MaxSize];
    int top;
} SqStack;

typedef struct Queue{
     BiTree data[MaxSize];
     int front,rear;
}SqQueue;


void InitStack(SqStack *S)
{
    S->top=-1;
}

bool Push(SqStack *S,BiTree T)
{
    if(S->top==MaxSize-1)return false;
    S->data[++S->top]=T;
    return true;
}


bool Pop(SqStack *S,BiTree *T)
{
    if(S->top==-1)return false;
    *T=S->data[S->top--];
    return true;
}

bool StackEmpty(SqStack *S){
    if(S->top==-1)return true;
    return false;
}

bool GetTop(SqStack *S,BiTree *T)
{
    if(S->top==-1)return false;
    *T=S->data[S->top];
    return true;
}

void InitQueue(SqQueue *Q)
{
    Q->front=0;
    Q->rear=0;
}

bool EnQueue(SqQueue *Q,BiTree T)
{
    if((Q->rear+1)%MaxSize==Q->front)return false;
    Q->data[Q->rear]=T;
    Q->rear=(Q->rear+1)%MaxSize;
    return true;
}

bool DeQueue(SqQueue *Q,BiTree *T)
{
    if(Q->front==Q->rear)return false;
    *T=Q->data[Q->front];
    Q->front=(Q->front+1)%MaxSize;
    return true;
}

bool QueueEmpty(SqQueue *Q)
{
    if(Q->front==Q->rear)return true;
    return false;
}



BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}
void visit(BiTree T)
{
    printf("%d ",T->data);
}


void  InvertLevel(BiTree T)
{
     SqStack S;SqQueue Q;
     if(T!=NULL)
     {
         InitStack(&S);
         InitQueue(&Q);
         EnQueue(&Q,T);
         BiTree p;
         while(!QueueEmpty(&Q))
         {
             DeQueue(&Q,&p);
             Push(&S,p);
             if(p->lchild!=NULL)
             {
                 EnQueue(&Q,p->lchild);
             }
             if(p->rchild!=NULL)
             {
                 EnQueue(&Q,p->rchild);
             }
         }
         while(!StackEmpty(&S))
         {
             Pop(&S,&p);
             visit(p);
         }
     }
}





int main()
{
    printf("请输入首结点: \n");
    BiTree T=CreateLink();// 1 2 -1 4 6 -1 -1 -1 3 -1 5 -1 -1
    InvertLevel(T); //6 5 4 3 2 1




    return 0;
}



第五题(非递归求二叉树高度)

利用层次遍历完成

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;




BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}

//非递归
int  Btdepth(BiTree T)
{

      if(!T)
      {
          return 0;
      }
      int front=-1,rear=-1;
      int last=0,level=0;
      BiTree Q[MaxSize];
      Q[++rear]=T;
      BiTree p;
      while(front<rear)
      {
          p=Q[++front];
          if(p->lchild)Q[++rear]=p->lchild;
          if(p->rchild)Q[++rear]=p->rchild;
          if(last==front){
             level++;
             last=rear;
          }
      }
      return level;
}


//递归遍历
int Btdepth2(BiTree T)
{
    if(T==NULL) return 0;
    int ldep=Btdepth2(T->lchild);
    int rdep=Btdepth2(T->rchild);
    if(ldep>rdep)
         return ldep+1;
    else return rdep+1;
}


int main()
{
    printf("请输入首结点: \n");
    BiTree T=CreateLink();// 1 2 -1 4 6 -1 -1 -1 3 -1 5 -1 -1
    printf("非递归结果: %d\n",Btdepth(T));
    printf("递归遍历结果: %d\n",Btdepth2(T));



    return 0;
}



第六题(给出先序、中序序列构造二叉树)

1、根据先序序列确定根节点
2、根据根节点在中序序列中的位置划分左右子树
3、依次递归(注意递归中下标求法)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;



BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}


BiTree PreInCreat(Elemtype A[],Elemtype B[],int l1,int h1,int l2,int h2)
{
    //l1、h1表示当前树在先序序列第一个下标和最后一个下标,同理l2,h2
    BiTree root=(BiTNode*)malloc(sizeof(BiTNode));//分配空间
    root->data=A[l1];
    int i;
    for(i=l2; B[i]!=root->data; i++); //在中序序列中找到根节点位置
    int llen=i-l2;//左子树元素个数
    int rlen=h2-i;
    if(llen)
        root->lchild=PreInCreat(A,B,l1+1,l1+llen,l2,l2+llen-1);
    else
        root->lchild=NULL;

    if(rlen)
        root->rchild=PreInCreat(A,B,h1-rlen+1,h1,h2-rlen+1,h2);
    else
        root->rchild=NULL;
    return root;
}

void visit(BiTree T)
{
    printf("%d  ",T->data);
}

void PreOrder(BiTree T)
{
    if(T!=NULL)
    {
        visit(T);
        PreOrder(T->lchild);
        PreOrder(T->rchild);
    }
}

int main()
{


    int n;
    int A[50]= {0},B[50]= {0};
    printf("请读入树结点个数\n");// 9
    scanf("%d",&n);
    printf("请输入先序序列:\n");
    // 1 2 3 4 5 6 7 8 9
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&A[i]);
    }
    printf("请输入中序序列:\n");
    // 2 3 1 5 4 7 8 6 9
    for(int i=1; i<=n; i++)
    {
        scanf("%d",&B[i]);
    }
    BiTree root=PreInCreat(A,B,1,n,1,n);
    printf("当前树的前序遍历序列为:\n");
    PreOrder(root);










    return 0;
}



第七题(利用层次遍历判断是否为完全二叉树)

//队列中放不进NULL 不会解决...
bool  IsComplete(BiTree T)
{
    Queue q;
    InitQueue(&q);
    if(!T)return 1;
    EnQueue(&q,T);
    BiTree p;
    while(!IsEmpty(&q))
    {
        DeQueue(&q,&p);
        printf("%d\n",p->data);
        if(p)
        {   
            EnQueue(&q,p->lchild);
            EnQueue(&q,p->rchild);
        }else{
            while(!IsEmpty(&q))
            {
                DeQueue(&q,&p);
                if(p)return 0;
            }
        }
    }
    return 1;
}

第八题(利用递归判断双分支结点个数)

f(b)=0 // b为NULL
f(b)=f(lb)+f(rb)+1 //当前结点为双分支结点
f(b)=f(lb)+f(rb) //单分支或叶节点

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}


int DsonNodes(BiTree b)
{
    if(b==NULL)return 0;
    else if(b->lchild!=NULL&&b->rchild!=NULL)
        return DsonNodes(b->lchild)+DsonNodes(b->rchild)+1;
    else return DsonNodes(b->lchild)+DsonNodes(b->rchild);
}


int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1
    printf("双分支结点个数为: %d",DsonNodes(root)); // 2





    return 0;
}



第九题(递归交换左右子树)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


typedef struct Queue
{
    BiTree data[MaxSize];
    int front,rear;
} Queue;

bool InitQueue(Queue *q)
{
    q->front=0;
    q->rear=0;
    return true;
}

bool EnQueue(Queue *q,BiTree T)
{
    if((q->rear+1)%MaxSize==q->front)return false;
    q->data[q->rear]=T;
    q->rear=(q->rear+1)%MaxSize;
    return true;
}

bool DeQueue(Queue *q,BiTree *T)
{
    if(q->rear==q->front)return false;
    *T=q->data[q->front];
    q->front=(q->front+1)%MaxSize;
    return true;
}

bool IsEmpty(Queue *q)
{
    if(q->front==q->rear)return true;
    return false;
}

BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}

void  swap(BiTree b)
{
     if(b)
     {
         swap(b->lchild);//递归交换左子树
         swap(b->rchild);//递归交换右子树
         BiTree temp=b->lchild;
         b->lchild=b->rchild;
         b->rchild=temp;
     }
}

void PreOrder(BiTree root)
{
    if(root)
    {
         printf("%d ",root->data);
         PreOrder(root->lchild);
         PreOrder(root->rchild);
    }
}
int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1   
    swap(root);
    printf("交换后前序遍历结果为:\n");
    PreOrder(root); //  1 3 2 5 4  (原来12453)











    return 0;
}



第十题(寻找前序遍历下标为i的结点元素)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


typedef struct Queue
{
    BiTree data[MaxSize];
    int front,rear;
} Queue;

bool InitQueue(Queue *q)
{
    q->front=0;
    q->rear=0;
    return true;
}

bool EnQueue(Queue *q,BiTree T)
{
    if((q->rear+1)%MaxSize==q->front)return false;
    q->data[q->rear]=T;
    q->rear=(q->rear+1)%MaxSize;
    return true;
}

bool DeQueue(Queue *q,BiTree *T)
{
    if(q->rear==q->front)return false;
    *T=q->data[q->front];
    q->front=(q->front+1)%MaxSize;
    return true;
}

bool IsEmpty(Queue *q)
{
    if(q->front==q->rear)return true;
    return false;
}

BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}
int i;
Elemtype e;
void  PreNode(BiTree b,int k)
{
    if(b)
    {
        i++;
        if(i==k)
        {
            e=b->data;
            return;
        }
        PreNode(b->lchild,k);
        PreNode(b->rchild,k);
    }
}

void PreOrder(BiTree root)
{
    if(root)
    {
        printf("%d ",root->data);
        PreOrder(root->lchild);
        PreOrder(root->rchild);
    }
}
int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1
    printf("请输入下标:\n");
    int k;
    scanf("%d",&k);
    PreNode(root,k);
    printf("下标为%d所对应元素值为:%d",k,e);





    return 0;
}



第十一题(删除所有以x元素为根的子树)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


typedef struct Queue
{
    BiTree data[MaxSize];
    int front,rear;
} Queue;

bool InitQueue(Queue *q)
{
    q->front=0;
    q->rear=0;
    return true;
}

bool EnQueue(Queue *q,BiTree T)
{
    if((q->rear+1)%MaxSize==q->front)return false;
    q->data[q->rear]=T;
    q->rear=(q->rear+1)%MaxSize;
    return true;
}

bool DeQueue(Queue *q,BiTree *T)
{
    if(q->rear==q->front)return false;
    *T=q->data[q->front];
    q->front=(q->front+1)%MaxSize;
    return true;
}

bool IsEmpty(Queue *q)
{
    if(q->front==q->rear)return true;
    return false;
}

BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}

//递归删除子树
void DeleteXTree(BiTree bt)
{
    if(bt)
    {
        DeleteXTree(bt->lchild);
        DeleteXTree(bt->rchild);
        free(bt);
    }
}

//层次遍历寻找值为x的子树
void Search(BiTree bt,Elemtype x)
{
    Queue q;
    InitQueue(&q);
    if(bt)
    {
        if(bt->data==x)
        {
            DeleteXTree(&bt);
            exit(0);
        }
        EnQueue(&q,bt);
        BiTree p;
        while(!IsEmpty(&q))
        {
            DeQueue(&q,&p);
            if(p->lchild)
            {
                if(p->lchild->data==x)
                {
                    DeleteXTree(p->lchild);//删除左子树
                    p->lchild=NULL;
                }
                else EnQueue(&q,p->lchild);
            }
            if(p->rchild)
            {
                if(p->rchild->data==x)
                {
                    DeleteXTree(p->rchild);//删除右子树
                    p->rchild=NULL;
                }
                else EnQueue(&q,p->rchild);
            }
        }
    }
}

void  PreOrder(BiTree bt)
{
    if(bt)
    {
        printf("%d ",bt->data);
        PreOrder(bt->lchild);
        PreOrder(bt->rchild);
    }
}

int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1
    printf("请输入删除元素:\n");
    int k;
    scanf("%d",&k);
    Search(root,k);
    printf("删除后的前序遍历结果\n");
    PreOrder(root);











    return 0;
}



第十二题(删除元素x的所有祖先)

利用后序遍历特点,当访问到x前将所有祖先入栈,当访问到x,直接将栈中元素依次出栈

仔细体会非递归后续遍历,右转的过程和细节

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}



typedef struct{
    BiTree t;
    int  tag;//tag=0表示访问过左子树,tag=1表示访问过右子树
}stack;

void  Search(BiTree bt,Elemtype x)
{
    stack s[MaxSize];
    int top=0;
    while(bt!=NULL||top>0)
    {
         while(bt!=NULL&&bt->data!=x) //一直向左将左孩子入栈,一直到找到x
         {
             s[++top].t=bt;
             s[top].tag=0;
             bt=bt->lchild;
         }
         if(bt!=NULL&&bt->data==x){
             printf("所查结点的所有祖先结点的值为:\n");
             for(int i=1;i<=top;i++){
                printf("%d ",s[i].t->data);
             }
             exit(1);
         }
         while(top!=0&&s[top].tag==1)top--; //右转后回来出栈
         if(top!=0)
         {
             s[top].tag=1;
             bt=s[top].t->rchild; //向右转
         }
    }

}



int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1
    printf("请输入删除元素:\n");
    int k;
    scanf("%d",&k);
    Search(root,k);



    return 0;
}


第十三题(利用后续遍历寻找最近公共祖先)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}



typedef struct
{
    BiTree t;
    int  tag;//tag=0表示访问过左子树,tag=1表示访问过右子树
} stack;
stack s[MaxSize],s1[MaxSize];

BiTree Ancestor(BiTree root,BiTree p,BiTree q)
{
    int top=0,top1=0;
    BiTree bt=root;
    while(bt!=NULL||top>0)
    {
        while(bt!=NULL) //沿左分支向下
        {
            s[++top].t=bt;
            s[top].tag=0;
            bt=bt->lchild;
        }
        while(top!=0&&s[top].tag==1)
        {
            if(s[top].t==p)  //找到p了,将栈元素复制到s1
            {
                for(int i=1; i<=top; i++)
                {
                    s1[i]=s[i];
                }
                top1=top;
            }
            if(s[top].t==q) //找到q元素,此时s中存放全部为q的祖先,s1存放全部为p的祖先
            {
                for(int i=top; i>0; i--)
                {
                    for(int j=top1; j>0; j--)
                    {
                        if(s1[j].t==s[i].t)return s[i].t;
                    }
                }
            }
            top--;//防止循环出栈
        }
        if(top!=0) //右移
        {
            s[top].tag=1;
            bt=s[top].t->rchild;//向右下分支遍历
        }
    }
    return NULL;
}

//通过x值寻找结点
void  findTree(BiTree u,Elemtype x,BiTree *p)
{
    if(u)
    {
        if(u->data==x) *p=u;
        findTree(u->lchild,x,p);
        findTree(u->rchild,x,p);
    }
}
int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 -1 -1
    printf("请输入p结点的值,p在q的左侧\n");
    int px,qx;
    scanf("%d",&px);
    printf("请输入q结点的值\n");
    scanf("%d",&qx);
    BiTree p,q;
    findTree(root,px,&p);
    findTree(root,qx,&q);
    BiTree ancestor=Ancestor(root,p,q);
    printf("最近公共祖先为: %d",ancestor->data);












    return 0;
}



第十四题(利用层次遍历求最大宽度)

在层次遍历中,在队列中设置level数组记录每个元素的层数
最后统计每层有多少个元素

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}



typedef struct
{
    BiTree data[MaxSize];
    int level[MaxSize];
    int front,rear;
}Qu;

int  BTWidth(BiTree  b)
{
    BiTree p;
    int k,max,i,n;
    Qu Qu;
    Qu.front=Qu.rear=1;
    Qu.data[Qu.rear]=b;
    Qu.level[Qu.rear]=1;
    //层次遍历,并且记录每个元素层数
    while(Qu.front<=Qu.rear)
    {
        p=Qu.data[Qu.front];
        k=Qu.level[Qu.front++];
        if(p->lchild)
        {
            Qu.data[++Qu.rear]=p->lchild;
            Qu.level[Qu.rear]=k+1;
        }
        if(p->rchild)
        {
            Qu.data[++Qu.rear]=p->rchild;
            Qu.level[Qu.rear]=k+1;
        }
    }
    max=0,i=1;
    k=1;
    while(i<=Qu.rear)
    {
        n=0;//统计第k层结点个数
        while(i<=Qu.rear&&Qu.level[i]==k)
        {
            n++;
            i++;
        }
        k=Qu.level[i];
        if(n>max)max=n;
    }
    return max;
}


int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1

    printf("此数最大宽度为: %d",BTWidth(root));// 4








    return 0;
}



第十五题(通过满二叉树前序序列得出后序序列)

#include 
#include 
#include

#define MaxSize 50

typedef char  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;




void PreToPost(Elemtype pre[],int l1,int h1,Elemtype post[],int l2,int h2)
{
    int half;
    if(h1>=l1)
    {
        post[h2]=pre[l1];
        half=(h1-l1)/2;
        PreToPost(pre,l1+1,l1+half,post,l2,l2+half-1);
        PreToPost(pre,l1+half+1,h1,post,l2+half,h2-1);
    }
}


int main()
{

   Elemtype *pre="ABCDEFG";
   Elemtype post[MaxSize];
   PreToPost(pre,0,6,post,0,6);
   printf("后序序列为:\n");
   for(int i=0;i<=6;i++)
   {
       printf("%c ",post[i]);
   }









    return 0;
}



第十六题(将二叉树叶子结点相连)

利用先序后序中序都可以实现

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}

BiTree head,pre=NULL;

BiTree InOrder(BiTree bt)
{
    if(bt)
    {
        InOrder(bt->lchild);
        if(bt->lchild==NULL&&bt->rchild==NULL)
        {
            if(pre==NULL)
            {
                head=bt;
                pre=bt;
            }else{
               pre->rchild=bt;
               pre=bt;
            }
        }
        InOrder(bt->rchild);
        pre->rchild=NULL;
    }
    return head;
}

void  PrintLeaves(BiTree head)
{
    if(head)
    {
        printf("%d ",head->data);
        PrintLeaves(head->rchild);
    }
}

int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree root=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1

    BiTree head=InOrder(root);
    PrintLeaves(head); // 4 5 6 7








    return 0;
}

第十七题(判断两颗树是否相似)

相似:形状相同

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}



int similar(BiTree T1,BiTree T2)
{
    int leftS,rightS;
    if(T1==NULL&&T2==NULL)
    {
        return 1;
    }else if(T1==NULL||T2==NULL)
    {
        return 0;
    }else{
        leftS=similar(T1->lchild,T2->lchild);
        rightS=similar(T1->rchild,T2->rchild);
        return leftS&&rightS;
    }
}



int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree T1=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1
    printf("请输入第二颗树\n");
    BiTree T2=CreateLink();
    printf("两棵树是否相似? %d",similar(T1,T2));









    return 0;
}

第十八题(中序线索树中寻找后序前驱结点)

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
    int ltag,rtag;
} ThreadNode,*ThreadTree;

ThreadTree pre;

ThreadTree CreateLink()
{
    int data;
    ThreadTree T;

    scanf("%d",&data);

    if(data==-1)return NULL;
    else
    {
        T=(ThreadTree)malloc(sizeof(ThreadNode));
        T->data=data;
        T->ltag=0,T->rtag=0;
        printf("请输入%d的左子树: ",T->data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: ",T->data);
        T->rchild=CreateLink();
        return T;
    }
}

//中序线索化
void InThread(ThreadTree p)
{
    if(p!=NULL)
    {
        InThread(p->lchild);
        if(p->lchild==NULL)
        {
            p->lchild=pre;
            p->ltag=1;
        }
        if(pre!=NULL&&pre->rchild==NULL)
        {
            pre->rchild=p;
            pre->rtag=1;
        }
        pre=p;
        InThread(p->rchild);
    }
}

void CreateInThread(ThreadTree T)
{
    if(T!=NULL)
    {
        InThread(T);
        pre->rchild=NULL;
        pre->rtag=1;
    }
}

ThreadTree Firstnode(ThreadTree p)
{
    while(p->ltag==0)p=p->lchild;
    return p;
}

ThreadTree Nextnode(ThreadTree p)
{
    if(p->rtag==0)return Firstnode(p->rchild);
    else return p->rchild;
}

void visit(ThreadTree p)
{
    printf("%d  ",p->data);
}

void InOrder(ThreadTree T)
{
    for(ThreadTree p=Firstnode(T); p!=NULL; p=Nextnode(p))
        visit(p);
}

ThreadTree FindByValue(ThreadTree T,Elemtype val)
{
    for(ThreadTree p=Firstnode(T);p!=NULL;p=Nextnode(p))
        if(p->data==val)return p;
}
//在中序线索化中,求后序遍历中的前驱结点
ThreadTree InPostPre(ThreadTree p)
{
    ThreadTree q;

    if(p->rtag==0) q=p->rchild; //存在右孩子
    else if(p->ltag==0)q=p->lchild; //存在左孩子(注意先后顺序)
    else if(p->lchild==NULL)q=NULL;
    else{

        while(p->ltag==1&&p->lchild!=NULL)
            p=p->lchild;

        if(p->ltag==0)q=p->lchild;
        else q=NULL; //一串都只有右孩子情况
    }
    return q;
}



int main()
{


    ThreadTree T;
    printf("请输入根节点数据: ");
    T=CreateLink();// 1 2 -1 4 6 -1 -1 -1 3 -1 5 -1 -1
    printf("输入完成\n");
    CreateInThread(T);
    printf("线索化完成\n");
    InOrder(T);// 2 6 4 1 3 5
    printf("\n请输入要查找中序线索树中后续前驱结点的元素值:\n");
    Elemtype v;
    scanf("%d",&v);// 4 
    ThreadTree p=FindByValue(T,v);
    ThreadTree q=InPostPre(p);
    printf("后序前驱结点值为:%d",q->data);//6



    return 0;
}

第十九题(二叉树的带权路径和)

1、递归
2、采用层次遍历

#include 
#include 
#include

#define MaxSize 50

typedef int  Elemtype;

typedef struct BiTNode
{

    Elemtype data;
    struct BiTNode * lchild,*rchild;
} BiTNode,*BiTree;


BiTree CreateLink()
{
    Elemtype data;
    BiTree T;
    scanf("%d",&data);
    if(data==-1)return NULL;
    else
    {
        T=(BiTree)malloc(sizeof(BiTNode));
        T->data=data;
        printf("请输入%d的左子树: \n",data);
        T->lchild=CreateLink();
        printf("请输入%d的右子树: \n",data);
        T->rchild=CreateLink();
        return T;
    }
}

//递归版本带权路径长度
int Wpl(BiTree root)
{
    return wpl_PreOrder(root,0);
}

int wpl_PreOrder(BiTree root,int deep)
{
    static int wpl=0;
    if(root->lchild==NULL&&root->rchild==NULL)
        wpl+=deep*root->data;
    if(root->lchild!=NULL)
        wpl_PreOrder(root->lchild,deep+1);
    if(root->rchild!=NULL)
        wpl_PreOrder(root->rchild,deep+1);

    return wpl;
}

//采用层次遍历
int  Wpl_Level(BiTree root)
{
    BiTree q[MaxSize];
    int front=0,rear=0;
    BiTree lastNode=root;
    BiTree newlastNode;
    q[rear++]=root;
    int wpl=0,deep=0;
    while(front!=rear)
    {
        BiTree t=q[front++];
        if(t->lchild==NULL&&t->rchild==NULL)
        {
            wpl+=deep*t->data;
        }
        if(t->lchild!=NULL)
        {
            q[rear++]=t->lchild;
            newlastNode=t->lchild;
        }
        if(t->rchild!=NULL)
        {
            q[rear++]=t->rchild;
            newlastNode=t->rchild;
        }
        if(t==lastNode){
            lastNode=newlastNode;
            deep+=1;
        }
    }
    return wpl;
}


int main()
{

    printf("创建二叉树,输入-1表示结束创建\n");
    BiTree T1=CreateLink();
    //1 2 4 -1 -1 5 -1 -1 3 6 -1 -1 7 -1 -1
    printf("采用先序遍历递归求wpl值为: %d\n",Wpl(T1));//44
    printf("采用层次遍历求wpl值为: %d",Wpl_Level(T1));//44









    return 0;
}

第二十题(中缀表达式的遍历添加括号)

void  BtreeToE(BiTree root)
{
    BtreeToExp(root,1);
}

void BtreeToExp(BiTree root,int deep)
{
    if(root==NULL)return ;
    else if(root->lchild==NULL&&root->rchild==NULL)
        printf("%c",root->data);
    else{
        if(deep>1)printf("(");
        BtreeToExp(root->lchild,deep+1);
        printf("%c",root->data);
        BtreeToExp(root->rchild,deep+1);
        if(deep>1)printf(")");
    }
}

你可能感兴趣的:(考研数据结构模板,#,王道数据结构习题,数据结构,c语言,链表)