二叉树的运用

二叉树算法C

定义语句:

typedef int itemType;
typedef struct BiTNode{
    itemType data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

1. 计算二叉树高度

//1.递归求二叉树高度
int Depth(BiTree T){
    int ldeep, rdeep;
    if(T == NULL){
        return 0;
    }
    ldeep = Depth(T->lchild);
    rdeep = Depth(T->rchild);
    if(ldeep > rdeep){
        return ldeep + 1;
    }else{
        return rdeep + 1;
    }
}
//2.先序遍历二叉树,可以得到所有结点的高度,比较得到最大高度
int maxLevel = 0;
void getHeight(BiTree T,int deep){
    if(T == NULL){
        return;
    }else{
        if(deep > maxLevel){
            maxLevel = deep;
        }
        getHeight(T->lchild,deep + 1);
        getHeight(T->rchild,deep + 1);
    }

}

2. 二叉树中序遍历输出表达式

在这里插入图片描述

//中序遍历基础上修改
//初始输入deep值为1
int BiTreeToExp(BiTree T,int deep){
    if(T == NULL){
        return 0;
    }
    if(T->lchild == NULL && T->rchild == NULL){   //当为叶子节点时,输出
        printf("%s",T->data); 
    }else{
        if(deep > 1){              // 当该节点有左子式时,输入(
            printf("(");
        }
        BiTreeToExp(T->lchild,deep + 1);
        printf("%s",T->data);
        BiTreeToExp(T->rchild,deep + 1);
        if(deep > 1){       //当该节点右子式输入结束时,输入)
            printf(")");
        }
    }
}

2. 二叉树后序计算表达式结果

仅有二元运算符,后序遍历计算达式

int PostToExp(BiTree T){
    int ldata,rdata;
    if(T == NULL){
        return 0;
    }
    if(T->lchild == NULL && T->rchild == NULL){
        return T->data;
    }else{
        ldata = PostToExp(T->lchild);
        rdata = PostToExp(T->rchild);
        return CalData(ldata,rdata,T->data);
    }
}

int CalData(int num1,int num2,char opt){
    switch(opt){
        case '+':
            return num1 + num2;
        case '-':
            return num1 - num2;
        case '*':
            return num1 * num2;
        case '/':
            if(!num2){
                printf("除数不能为0\n");
                exit(0);
            }
            return num1 / num2;
    }
}

3.找出二叉树中值为X的结点,并求出该结点的层数

int leafLevel = 0;
//初始deep值为1
void SearchLeaf(BiTree T,int x,int deep){
    if(T == NULL){
        return;
    }
    else if(T->data == x){
        leafLevel = deep;
    }else{
        SearchLeaf(T->lchild,x,deep + 1);
        SearchLeaf(T->rchild,x,deep + 1);
    }
}

4.求二叉树中值为X的节点,计算该结点子树的深度

先序遍历二叉树,找到该结点,然后计算高度可以用

  • void getHeight(BiTree T,int deep)
  • int depth(BiTree T)
int maxLevel = 0;
void preOrderTraverse(BiTree T,int x){
    if(T == NULL){
        return;
    }else if(T->data == x){
        getHeight(T,1);
        //maxLevel = Depth(T,1);
    }else{
        preOrderTraverse(T->lchild,x);
        preOrderTraverse(T->rchild,x);
    }
}
void  getHeight(BiTree T,int deep){
    if(T == NULL){
        return 0;
    }else{
        if(deep > maxLevel){
            maxLevel = deep;
        }
        getHeight(T->lchild,deep + 1);
        getHeight(T->rchild,deep + 1);
    }

}

int Depth(BiTree T){
    int ldeep, rdeep;
    if(T == NULL){
        return 0;
    }
    ldeep = Depth(T->lchild);
    rdeep = Depth(T->rchild);
    if(ldeep > rdeep){
        return ldeep + 1;
    }else{
        return rdeep + 1;
    }
}

5.求二叉树中第i层和i+1层的叶子结点数目

int leafNum = 0; //叶子节点的数目
// deep为当前结点的深度,deep初始值为1
//i为二叉树的第i层
void preOrder(BiTNode T,int deep,int i){
    if(T == NULL){
        return;
    }
    if(deep == i || deep == i + 1){
        if(T->lchild == NULL && T->rchild == NULL){
            leafNum++;
        }
    }
    preOrder(T->lchild,deep + 1,i);
    preOrder(T->rchild,deep + 1,i);
}

6.求二叉树的最大宽度

定义语句

typedef int itemType;
typedef struct BiTNode{
    itemType data;
    struct BiTNode *lchild;
    struct BiTNode *rchild;
}BiTNode,*BiTree;

typedef struct QNode{
    BiTree data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct Queue{
    QueuePtr front,rear;
    int length;
}LinkQueue;

int EnQueue(LinkQueue *Q,BiTree T);
int DeQueue(LinkQueue *Q,BiTree *T);
int InitQueue(LinkQueue *Q);
//利用队列按层次遍历二叉树,
//每次队列中均为当前层的所有结点,
//设置maxwidth,将每层的宽度与其进行比较
int getMaxWidth(BiTree T){
    int maxWidth;
    int len;  //当前层的节点数
    
    LinkQueue Q;
    InitQueue(&Q);
    EnQueue(&Q,T);
    
    maxWidth = 1;
    
    if(T == NULL){
        return 0;
    }
    
    while(1){
        len = Q->length;
        if(len == 0)
            break;
        while(len > 0){ 
        //将当前层的结点依次出队列
            DeQueue(*Q,&T);
            len--;
            //将左右孩子依次入队列
            if(T->lchild != NULL){
                EnQueue(Q,T->lchild);
            }
            if(T->rchild != NULL){
                EnQueue(Q,T->rchild);
            }
        }
        maxWidth = maxWidth > Q->length ? maxWidth : Q->length;
    }
    return maxWidth;
}

7.求树的度

用孩子兄弟链表存储(左孩子右兄弟)

int maxDegree = 0;
//通过先序遍历算法,遍历每个结点
void getDegreePreOder(BiTree T){
    int degree = 0;
    BiTree p = T;
    if(T == NULL){
        return;
    }else{
    	//计算每个结点的父节点的度,遍历右兄弟
        degree = 1;
        while(p->rchild != NULL){
            degree++;
            p = p->rchild;
        }
        //与最大度进行比较
        if(degree > maxDegree)
            maxDegree = degree;
        getDegreePreOder(T->lchild);
        getDegreePreOder(T->rchild);
    }
}

7.判断两棵树是否相等

先序遍历两颗二叉树,依次进行比较

//方法一:先序遍历两颗二叉树,每个结点依次比较
int compareTreePreOrder(BiTree T,BiTree P){
    if((T == NULL && P != NULL) || (T != NULL && P == NULL)){
        return 0;
    }else if(T == NULL && P == NULL){
        return 1;
    }else if(T->data != P->data){
        return 0;
    }else if(T->data == P->data){
        return compareTreePreOrder(T->lchild,P->lchild) && compareTreePreOrder(T->rchild,P->rchild);
    }
}
//方法二  先序和中序的结果进行比较
int compareTreePreOrder(BiTree T,BiTree P){
   1.先序遍历T和P,遍历结果装在数组(队列或者栈中)
   然后进行比较,如果相同就进行下一步
   2.中序遍历T和P,遍历结果装在数组(队列或者栈中)
   进行比较,如果相同就返回True
   {二叉树中序遍历和前序(后序)遍历可以唯一确定一颗二叉树}
}

8.查找结点X的祖先结点

定义语句

#define MAX_SIZE 100
typedef int itemType;
typedef struct Stack{
    itemType data[MAX_SIZE];
    int top;
}Stack;
Stack S;  //全局变量栈
int preOderFindParent(BiTree T,int x){
    int i,flag = 0;   //flag表示左右孩子是否找到结点x
    if(T){
        S.top++;
        S.data[S.top] = T->data;
        if(T->data == x){
            for(i = S.top - 1; i > -1;i--){
                printf("%c",S.data[i]);
            }
            return 1;
        }else{
            flag = preOderFindParent(T->lchild,x);
            //如果左孩子没有找到x结点就遍历右孩子
            if(!flag){
                flag = preOderFindParent(T->rchild,x);
            }
        }
        //左右孩子均遍历结束,且没有找到x,退出栈
        if(!flag)
        	S->top--;
    }
    return flag;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值