二叉树算法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;
}