notes:
1.global存了一些结构体,定义见后边
2.使用了队列,队列的操作的实现,见其他文章
3.使用了数学库,编译命令类似于 gcc -g tree.c -o tree -lm
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//global存了一些结构体
#include "Global.h"
//使用了队列
#include "LinkQueue.c"
//使用了数学库,编译命令类似于 gcc -g tree.c -o tree -lm
#include <math.h>
Tree InitTree(int data)
{
Tree head= (Tree)malloc(sizeof(TreeNode));
head->data=data;
head->lchild=NULL;
head->rchild=NULL;
return head;
}
Tree LeftInsertTree(Tree head,int data)
{
Tree temp=malloc(sizeof(TreeNode));
if (temp==NULL) return NULL;
temp->data=data;
temp->lchild=NULL;
temp->rchild=NULL;
head->lchild=temp;
return temp;
}
Tree RightInsertTree(Tree head,int data)
{
Tree temp=malloc(sizeof(TreeNode));
if (temp==NULL) return NULL;
temp->data=data;
temp->lchild=NULL;
temp->rchild=NULL;
head->rchild=temp;
return temp;
}
int InsertLeftAndRight(Tree head,Tree left,Tree right,int ldata,int rdata)
{
Tree lt=malloc(sizeof(TreeNode));
Tree rt=malloc(sizeof(TreeNode));
if(lt==NULL||rt==NULL) return -1;
lt->data=ldata;
lt->lchild=NULL;
lt->rchild=NULL;
rt->data=rdata;
rt->lchild=NULL;
rt->rchild=NULL;
head->lchild=lt;
head->rchild=rt;
left=lt;
right=rt;
return 1;
}
void Visit(Tree head)
{
printf(" %c ",head->data);
}
void PreOrder(Tree head)
{
if(head!=NULL)
{
Visit(head);
PreOrder(head->lchild);
PreOrder(head->rchild);
}
}
void InOrder(Tree head)
{
if (head!=NULL)
{
InOrder(head->lchild);
Visit(head);
InOrder(head->rchild);
}
}
void LevelOrder(Tree root)
{
LinkQueue queue;
Tree p;
InitLinkQueue(&queue);
EnQueue(&queue,root);
while(!IsEmpty(&queue))
{
DeQueue(&queue,&p);
Visit(p);
if (p->lchild!=NULL)
{
EnQueue(&queue,p->lchild);
}
if (p->rchild!=NULL)
{
EnQueue(&queue,p->rchild);
}
}
}
int GetTreeHight(Tree root)
{
if(root==NULL) return 0;
int front=-1,rear=-1;
int last=0,level=0;
Tree Q[MaxSize];
Q[++rear]=root;
Tree p;
//队列非空
while(front<rear)
{
p=Q[++front];
if (p->lchild!=NULL)
{
Q[++rear]=p->lchild;
}
if (p->rchild!=NULL)
{
Q[++rear]=p->rchild;
}
//到了一层的层尾
if (front==last)
{
level++;
//此时下一层已经全部如队,此层已经全部出对
last=rear;
}
}
return level;
}
int GetTreeWight(Tree root)
{
if (root==NULL)
{
return 0;
}
Tree Q[MaxSize];
int rear=-1,front=-1;
int level=0,last=0;
int count=0;
Tree p;
//注意越界,但是我不会写动态分配的代码,emmm
int wights[10]={0,0};
Q[++rear]=root;
while(front<rear)
{
p=Q[++front];
count++;
if (p->lchild!=NULL)
{
Q[++rear]=p->lchild;
}
if (p->rchild!=NULL)
{
Q[++rear]=p->rchild;
}
if (last==front)
{
wights[level]=count;
count=0;
level++;
last=rear;
}
}
int i=0,max=0;
for (int i = 0; i < 10; i++)
{
if (wights[i]>max) max=wights[i];
}
return max;
}
//根据先序遍历序列和中序遍历序列建立一个二叉树
//先序:ABCDEFGHI
//中序:BCAEDGHFI
//l1 0 l2=8 l2 0 h2 8
//i=2 h2-i=6 l2=2
Tree PreInCreat(char PreQueen[],char InQueen[],int l1,int h1,int l2,int h2)
{
//l1 l2指向先序和中序的第一个元素
//h1 h2指向先序和中序的最后一个元素
//首先根据先序序列找到根节点
Tree root=InitTree(PreQueen[l1]);
//根据中序序列找到左子数的元素,和右子树的元素
int i=0,llen=0,rlen=0;
for (i = l2; root->data!=InQueen[i]; i++);
llen=i-l2;
rlen=h2-i;
//注意,在递归建立时注意不要改变值,也就是如果表达i往后移动一位,不能是i++而是i+1
//尽量不使用i表达
if (llen!=0)
root->lchild=PreInCreat(PreQueen,InQueen,l1+1,l1+llen,l2,l2+llen-1);
else
root->lchild=NULL;
if (rlen!=0)
root->rchild=PreInCreat(PreQueen,InQueen,h1-rlen+1,h1,h2-rlen+1,h2);
else
root->rchild=NULL;
return root;
}
//利用层次遍历的思想 判断是不是完全二叉树 垃圾版
//贼垃圾,不要看
int Low_IsFullTree(Tree root)
{
if (root==NULL) return -1;
int last=0,level=0;
int count=0;
int front=-1,rear=-1;
int heigth=GetTreeHight(root);
Tree Q[MaxSize];
Tree p;
//入队
Q[++rear]=root;
while (front<rear)
{
//出队
p=Q[++front];
//每次如队列一个就加一可以统计每层的个数
count++;
if (p->lchild!=NULL)
{
Q[++rear]=p->lchild;
}
if (p->rchild!=NULL)
{
Q[++rear]=p->rchild;
}
//如果队列的前指针指向了last
//说明这一层遍历完了
if (last==front&&level!=heigth-2)
{
level++;
//刚遍历完时,rear指向这一层的尾节点
last=rear;
//看看这一层是不是满的
//不是满的有两种情况,第一种不是完全二叉树
//第二种,最后一层
//如果不进if说明是满二叉树
if (pow(2,level-1)!=count)
{
return 0;
}
//这层完了,下一层重新计数
count=0;
}
//刚进倒数第二层,遍历每一个节点
if(level==heigth-2)
{
int flag_1=1,flag_2=0;
int t_front=front,t_rear=rear;
int i=0;
while(t_front-t_rear!=1)
{
if (Q[t_front]->lchild==NULL || Q[t_front]->rchild==NULL)
{
if (flag_1==1) flag_2++;
}
else
{
if(flag_1==0) flag_2++;
}
if(flag_2==2||flag_2>2) return 0;
t_front++;
}
}
}
return 1;
}
//升级版 是不是完全二叉树
int IsFullTree_Pro(Tree root)
{
int front=-1,rear=-1;
Tree Q[MaxSize];
Q[++rear]=root;
Tree p;
while(front==rear)
{
p=Q[++front];
if (p!=NULL)
{
Q[++rear]=p->lchild;
Q[++rear]=p->rchild;
}
else
{
Q[++rear]=NULL;
}
}
int i=0;
while(i!=rear)
{
if (Q[i]==NULL)
{
int j=i+1;
while(j!=rear)
{
if (Q[j]!=NULL)
{
return 0;
}
}
}
i++;
}
}
//计算所以双分支节点个数,层次遍历写法
int DoubelChildCount(Tree root)
{
if (root==NULL) return 0;
LinkQueue *queue;
InitLinkQueue(queue);
EnQueue(queue,root);
Tree p;
int count=0;
while(!IsEmpty(queue))
{
DeQueue(queue,p);
if (p->lchild!=NULL&&p->rchild!=NULL)
{
count++;
}
if (p->lchild!=NULL)
{
EnQueue(queue,p->lchild);
}
if (p->rchild!=NULL)
{
EnQueue(queue,p->rchild);
}
}
}
//递归写法,计算所有双分支节点的个数
int DoubelChildCount_digui(Tree root)
{
if (root==NULL)
{
return 0;
}
else if (root->lchild!=NULL&&root->rchild!=NULL)
{
return DoubelChildCount_digui(root->lchild)+DoubelChildCount_digui(root->rchild)+1;
}
else
{
return DoubelChildCount_digui(root->lchild)+DoubelChildCount_digui(root->rchild);
}
}
//层次遍历交换左右节点
int ChangeLeftAndRight(Tree root)
{
if (root==NULL) return 0;
LinkQueue *queue;
InitLinkQueue(queue);
EnQueue(queue,root);
Tree p,temp;
int count=0;
while(!IsEmpty(queue))
{
DeQueue(queue,p);
//交换节点
temp=p->rchild;
p->rchild=p->lchild;
p->lchild=temp;
//此时左右分支还没有进入队列
if (p->lchild!=NULL)
{
EnQueue(queue,p->lchild);
}
if (p->rchild!=NULL)
{
EnQueue(queue,p->rchild);
}
}
}
//递归交换左右节点
void ChangeLeftAndRight_digui(Tree root)
{
if (root==NULL)
{
return ;
}
else
{
Tree temp;
temp=root->lchild;
root->lchild=root->rchild;
root->rchild=temp;
ChangeLeftAndRight_digui(root->lchild);
ChangeLeftAndRight_digui(root->rchild);
}
}
//根据根节点删除一棵树
void Delete(Tree root)
{
if (root!=NULL)
{
Delete(root->lchild);
Delete(root->rchild);
//左右节点都被删除完了,此节点必然左右为空
free(root);
}
return ;
}
//删除节点是x的的节点,并删除以x为根节点的树
void DeleteX(Tree root,char x)
{
if (root!=NULL)
{
//检查该节点是不是x
if (root->data==x)
{
Delete(root);
}
//递归访问左右节点
DeleteX(root->lchild,x);
DeleteX(root->rchild,x);
}
return ;
}
//打印值为x的节点的所有祖先
int PrintXParents(Tree root,char x)
{
if (root!=NULL)
{
if (root->data==x)
{
printf(" %c",root->data);
return 1;
}
int flag_1= PrintXParents(root->lchild,x);
if (flag_1==1)
{
printf(" %c",root->data);
return 1;
}
int flag_2= PrintXParents(root->rchild,x);
if (flag_2==1)
{
printf(" %c",root->data);
return 1;
}
}
return 0;
}
//根据先序建立满二叉树,递归吧,递归好写阿红红火火
Tree FullQueueCreatTree(char queue[],int begin,int end)
{
//别着急,先检查以下序列,如果是满二叉树的序列应该个数上有限制
int i=0,len=end-begin+1,child_len=(end-begin)/2;
while(1)
{
//正好等比求和是他
if ((pow(2,i)-1)==len) break;
//i只会越来越大,不可能再次相等
if (pow(2,i)>len) return NULL;
i++;
}
Tree root=malloc(sizeof(TreeNode));
//头节点已经建好,递归建立左右子树
root->data=queue[begin];
if (begin==end)
{
return root;
}
root->lchild=FullQueueCreatTree(queue,begin+1,begin+child_len);
root->rchild=FullQueueCreatTree(queue,begin+child_len+1,end);
return root;
}
int main()
{
char PreQueen[]="ABCDEFGHI";
char InQueen[]="BCAEDGHFI";
printf("%s,%s",PreQueen,InQueen);
Tree head=PreInCreat(PreQueen,InQueen,0,8,0,8);
PreOrder(head);
InOrder(head);
LevelOrder(head);
printf("%d\n",GetTreeHight(head));
printf("-------find x parents--------\n");
PrintXParents(head,'E');
printf("\n-------get root wights--------\n");
printf("%d\n",GetTreeWight(head));
printf("\ncreat tree\n");
Tree root=FullQueueCreatTree("ABDECFG",0,6);
PreOrder(root);
}
//2014年 真题
// typedef struct WPL_Tree
// {
// struct WPL_Tree *left,*right;
// int weight;
// } *WTree;
// int PreOrderWPL(WTree root,int deep)
// {
// int wpl=0;
// if (root->right==NULL&&root->left==NULL)
// {
// return deep*root->weight;
// }
// if (root->left!=NULL)
// {
// wpl+=PreOrderWPL(root->left,deep+1);
// }
// if (root->right!=NULL)
// {
// wpl+=PreOrderWPL(root->right,deep+1);
// }
// return wpl;
// }
//2017年真题
// typedef struct node
// {
// char data[10];
// struct node *left,*right;
// } BTree;
// char* GetExpress(BTree *root,int deep)
// {
// char * ex=NULL;
// if (root!=NULL)
// {
// char op=root->data;
// if (deep==1)
// {
// char *a= GetExpress(root->left,deep+1);
// char *b= GetExpress(root->right,deep+1);
// ex=*a+op+*b;
// }
// if (root->left==NULL&&root->right==NULL)
// {
// return root->data;
// }
// char *a= GetExpress(root->left,deep+1);
// char *b= GetExpress(root->right,deep+1);
// ex='('+*a+')'+op+'('+*b+')';
// }
// return ex;
// }
#ifndef __GLOBAL_H__
#define MaxSize 255
typedef struct TreeNode
{
char data;
struct TreeNode *lchild,*rchild;
} TreeNode,*Tree;
//数据类型定义
typedef struct LinkNode
{
Tree data;
struct LinkNode *next;
} LinkNode;
typedef struct
{
LinkNode *front,*rear;
} LinkQueue;
void InitLinkQueue(LinkQueue *queue);
void EnQueue(LinkQueue *queue,Tree data);
int DeQueue(LinkQueue *queue, Tree *data);
#define __GLOBAL_H__
#endif