/*
二叉树的应用(二叉树)
[问题描述]
编程实现二叉树的建立,先序、中序、后序(递归和非递归方法)、层序遍历,二叉树的高度、繁茂度,
交换左右子树,统计叶子节点的数目,判断是否为完全二叉树,按树的形态在屏幕上打印输出。
[基本要求]
(1) 从文件中读入建树信息,树的节点数目不小于20个,树的高度不小于4。
(2) 建树信息采用两行英文字符表示,每个英文字符代表一个结点,第1行为树的中序遍历结果,
第2行为树的后序遍历结果。
[名词注释]
二叉树的繁茂度:为各层结点数的最大值与树的高度的乘积
完全二叉树:
a:所有节点只可能出现在最大的两层上
b:对于任何节点,若其右子树的层高为k,则其左子树可能为k或者是k+1
*/
#include <stdio.h>
#include <malloc.h>
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
//树型结构体
typedef struct Node
{
char data;
struct Node *Lchild;
struct Node *Rchild;
}BiTNode,*BiTree;
//栈元素结构体
typedef struct node
{
BiTree tree;
struct node *next;
}seqstack,*stack;
//队列元素结构体
typedef struct node1
{
BiTree tree;
struct node1 *next;
} Qnode;
//队列的队头和队尾元素指针
typedef struct
{
Qnode *front;
Qnode *rear;
}LQnode;
//用于统计每一层叶子节点个数
typedef struct
{
int countleaf[10];
int countpoint[10];
int depth;
}countPoint;
/*typedef struct
{
char mid[100];
char post[100];
}tree; */
countPoint point;
//用于统计节点数的全局变量
int count1=0,count2=0;
//用于寻根函数
BiTree tree[100];
int i=0;
//tree list;//定义存储树序列的全局变量
stack init_seq();//初始化空栈,创建站顶元素,返回栈顶指针
int isempty(stack sq);//置栈空
void push(stack sq,BiTree tr);//进栈
void pop(stack sq,BiTree *p);//出栈
BiTree top(stack sq);//取栈顶数据
LQnode *init_LQnode();
int isempty_L(LQnode *q);
void in_LQnode(LQnode *q,BiTree tr);
void out_LQnode(LQnode *q,BiTree *tr);
void creat_Btree(BiTree *root,FILE *fp);//创建树
void pre_visit(BiTree root);//非递归先序遍历
void re_pro_visit(BiTree root);//递归先序遍历
void mid_visit(BiTree root);//非递归中序遍历
void re_mid_visit(BiTree root);//递归中序遍历
void post_visit(BiTree root);//非递归先后序遍历
void re_post_visit(BiTree root);//递归先后序遍历
void leval_visit(BiTree root);//层次遍历
BiTree parent (BiTree root,BiTree leaf);//搜索双亲函数
void print_path(BiTree root);//打印路径函数
void swap_tree(BiTree root);//交换左右子树
void post_visit_point(BiTree root);//递归统计有两个孩子节点和至少有一个孩子的节点,间接统计只有一个孩子的节点
int mid_visit_leaf(BiTree root);//输出叶子节点个数和叶子节点
void pro_visit_leaf(BiTree root);//先序统计叶子节点
int postTreeDepth(BiTree root);//求树的深度
void printTree(BiTree root,int h);//打印树
int * count_leaf_Level(BiTree root,int k);//某一层k的叶子结点个数(待修改)
void print_count_leaf(BiTree root); //统计每一层的叶子节点个数
int Lush_degree(BiTree root);//二叉树的繁茂度
int IsComBinTree(BiTree root);//判定是否为完全二叉树
FILE * file();
void visit(char ch);
int main ()
{
system("title 树操作系统 ");
int leaf,depth;//叶子节点数和树的深度
FILE *fp;
BiTree root;
fp=FILE * file();
creat_Btree(&root,fp);//创建树
return 0;
}
/**********************界面操作*********************/
void main_menu()
{
int choice,choice1;
printf("\n\n\n\n");
printf("\n\t\t************欢迎进入树操作系统***********\n");
printf("\t\t \n");
printf("\t\t\t 1、遍历树\n");
printf("\t\t\t 2、交换左右子树\n");
printf("\t\t\t 3、输出叶子节点个数和叶子节点\n");
printf("\t\t\t 4、树的深度 \n");
printf("\t\t\t 5、统计每一层的叶子节点个数 \n");
printf("\t\t\t 6、判定是否为完全二叉树 \n");
printf("\t\t\t 7、二叉树的繁茂度 \n");
printf("\n\t\t************谢谢使用树操作系统***********\n");
InputBox(ch, 100, "请输入您的选择" );
sscanf(ch,"%d",&choice);
switch(choice)
{
case 1:{
system(cls);
printf("\n\n\n\n");
printf("\n\t\t************欢迎进入树操作系统***********\n");
printf("\t\t \n");
printf("\t\t\t 1、层次遍历\n");
printf("\t\t\t 2、非递归先序遍历\n");
printf("\t\t\t 3、递归先序遍历\n");
printf("\t\t\t 4、非递归中序遍历 \n");
printf("\t\t\t 5、递归中序遍历 \n");
printf("\t\t\t 6、非递归后序遍历 \n");
printf("\t\t\t 7、递归后序遍历 \n");
printf("\n\t\t************谢谢使用树操作系统***********\n");
InputBox(ch, 100, "请输入您的选择" );
sscanf(ch,"%d",&choice1);
break;
}
case 2:{swap_tree(root);break;}
case 3:{mid_visit_leaf(root);break;}
case 4:{postTreeDepth(BiTree root);;break;}
}
}
/********************栈操作 ***********************/
//初始化空栈,创建站顶元素,返回栈顶指针
stack init_seq()
{
stack sq;
sq=(stack)malloc(sizeof(seqstack));
sq->next=NULL;
return sq;
}
//置栈空
int isempty(stack sq)
{
if(sq->next==NULL)
return 1;
return 0;
}
//入栈函数
void push(stack sq,BiTree tr)
{
stack q;
q=(stack)malloc(sizeof(seqstack));
q->tree=tr;
q->next=sq->next;
sq->next=q;
// free(q);
}
//出栈函数
void pop(stack sq,BiTree *p)
{
// char *ch;
stack q;
q=sq->next;
sq->next=q->next;
(*p)=q->tree;
free(q);
}
//取栈顶元素
BiTree top(stack sq)
{
BiTree p;
if(!isempty(sq))
{
p=sq->next->tree;
}
return p;
}
/**********************队列操作*******************/
//初始化队列
LQnode *init_LQnode()
{
LQnode *q;
Qnode *p;
q=(LQnode*)malloc(sizeof(LQnode));
p=(Qnode*)malloc(sizeof(Qnode));
p->next=NULL;
q->front=q->rear=p;
return q;
}
int isempty_L(LQnode *q)
{
if(q->front==q->rear)
return 1;
else
return 0;
}
//入队
void in_LQnode(LQnode *q,BiTree tr)
{
Qnode *p;
p=(Qnode*)malloc(sizeof(Qnode));
p->tree=tr;
p->next=NULL;
q->rear->next=p;
q->rear=p;
}
//出队
void out_LQnode(LQnode *q,BiTree *tr)
{
if(!isempty_L(q))
{
Qnode *p;
p=(Qnode*)malloc(sizeof(Qnode));
p=q->front->next;
q->front->next=p->next;
*tr=p->tree;
free(p);
if(q->front->next==NULL)
q->rear=q->front;
}
}
/****************文件操作********************/
//打开文件操作
FILE * file()
{
FILE *fp;
char filename[]="树.txt";
fp=fopen(filename,"r");
if(fp==NULL)
{
printf("\n 打开文件失败,%s可能不存在,请先到对应文件夹下建立该文件!\n",filename);
exit(1);
}
return fp;
}
/********************文件操作**********************/
/********************二叉树操作**********************/
//扩展先序建立二叉树
//递归一次便给当前节点的数据域赋值,然后利用递归
//一次给该结点的左右子树赋值,实现二叉树的创建
void creat_Btree(BiTree *root,FILE *fp)
{
char ch;
ch=fgetc(fp);
if(ch==EOF)
return ;
if(ch=='#')
(*root)=NULL;
else{
(*root)=(BiTree)malloc(sizeof(BiTNode));
(*root)->data=ch;
creat_Btree(&((*root)->Lchild),fp);
creat_Btree(&((*root)->Rchild),fp);
}
}
//利用中序后序遍历建立二叉树
void creat_mid_post_tree(BiTree *root)
{
}
//非递归先序遍历
/* 首先对根节点和左子树以此访问并且顺序入栈,如果当前访问节点的左子树为空,
将该节点A退栈,访问该子树的右子树,对该节点的右子树按照上述方法进行遍历访问,访问完之后退回到,
A节点的双亲节点,将其退栈,同样的方法访问其右子树,以此类推访问完整个二叉树。
*/
void pre_visit(BiTree root)
{
stack s;
BiTree p;
s=init_seq();
p=root;
while(p!=NULL||!isempty(s))
{
while(p!=NULL)
{
visit(p->data);
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
pop(s,&p);
p=p->Rchild;
}
}
}
//递归实现先序遍历
void re_pro_visit(BiTree root)
{
if(root)
{
visit(root->data);
re_pro_visit(root->Lchild);
re_pro_visit(root->Rchild);
}
}
//非递归中序遍历
/* 首先通过循环不断将节点入栈,直到找到左子树的最左侧的节点,从该节点进行遍历,先访问该结点,然后退栈,访问根节点,
再然后进入该根节点的右子树,同样的方法进行访问,访问完之后,将该根节点的根节点退栈,同样的方法访问他的右子树,一直循环直至
栈为空且,辅助指针为空,表示二叉树访问完
*/
void mid_visit(BiTree root)
{
stack s;
BiTree p;
s=init_seq();
p=root;
while(p!=NULL||!isempty(s))
{
while(p!=NULL)
{
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
pop(s,&p);
visit(p->data);
p=p->Rchild;
}
}
}
//递归实现中序遍历
void re_mid_visit(BiTree root)
{
if(root)
{
re_mid_visit(root->Lchild);
visit(root->data);
re_mid_visit(root->Rchild);
}
}
//非递归后序遍历
/* 首先通过循环不断将节点入栈,直到找到左子树的最左侧的节点,然后取栈顶元素,即该结点,及对其右子树进行考察,
如果其右子树是空或者是已经访问过,则退栈,访问站顶元素,并将其地址赋值给第二辅助标记指针变量,并将第一指
针变量置为空,便于再退栈,访问下一个节点的数据,否则如果该节点的右子树不为空且未被访问过,则同样的访问该节点的右子树。
*/
void post_visit(BiTree root)
{
stack s;
s=init_seq();
BiTree p,q;
p=root;q=NULL;
while(!isempty(s)||p!=NULL)
{
while(p!=NULL)
{
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
p=top(s);
if((p->Rchild==NULL)||(p->Rchild==q))
{
pop(s,&p);
visit(p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}
//递归实现后序遍历
void re_post_visit(BiTree root)
{
if(root)
{
re_post_visit(root->Lchild);
re_post_visit(root->Rchild);
visit(root->data);
}
}
//层次遍历
void leval_visit(BiTree root)
{
LQnode *q;
q=init_LQnode();
BiTree p;
in_LQnode(q,root);
while(!isempty_L(q))
{
out_LQnode(q,&p);
visit(p->data);
if(p->Lchild!=NULL)
in_LQnode(q,p->Lchild);
if(p->Rchild!=NULL)
in_LQnode(q,p->Rchild);
}
}
/*
//主体部分分为查找叶子节点、寻找双亲函数和打印路径三部分
void pro_visit_leaf(BiTree root)
{
if(root)
{
if(root->Lchild==NULL&&root->Rchild==NULL)
{
tree[i]=root;
// visit(tree[i]->data);
i++;
}
pro_visit_leaf(root->Lchild);
pro_visit_leaf(root->Rchild);
}
}
*/
//搜索某一节点的双亲
BiTree parent (BiTree root,BiTree leaf)
{
BiTree p;
if(root==NULL)
return NULL;
if(root->Lchild==leaf||root->Rchild==leaf)
return root;
p=parent(root->Lchild,leaf);
if(p!=NULL)
return p;
else
return (parent(root->Rchild,leaf));
}
//打印某一节点到根节点的路径
void print_path(BiTree root)
{ BiTree p;
char ch[100];
int k;
for(int j=0;j<i;j++)
{
k=0;
p=tree[j];
// printf("%c:",p->data);
visit(p->data);
while(p->data!=root->data)
{
p=parent (root,p);
ch[k]=p->data;
k++;
}
while(k>=1)
{
visit(ch[k-1]);
k--;
}
printf("\n");
}
}
//交换左右子树
/*通过递归实现,原理就是将换两个变量的值*/
void swap_tree(BiTree root)
{
BiTree p;
p=root->Lchild;
root->Lchild=root->Rchild;
root->Rchild=p;
if(root->Lchild!=NULL)
swap_tree(root->Lchild);
if(root->Rchild!=NULL)
swap_tree(root->Rchild);
}
//递归统计有两个孩子节点和至少有一个孩子的节点,间接统计只有一个孩子的节点
void post_visit_point(BiTree root)
{
if(root)
{
if(root->Lchild!=NULL&&root->Rchild!=NULL)
count2++;//统计有两个孩子的节点个数
if((root->Lchild!=NULL||root->Rchild!=NULL))
count1++;//统计至少有一个孩子的节点个数
post_visit_point(root->Lchild);
post_visit_point(root->Rchild);
}
}
//输出叶子节点个数和叶子节点
int mid_visit_leaf(BiTree root)
{
int leaf1=0,leaf2=0;
if(root)
{
if(root->Lchild==NULL&&root->Rchild==NULL)
{
tree[i]=root;
i++;
visit(root->data);
return 1;
}
leaf1=mid_visit_leaf(root->Lchild);
leaf2=mid_visit_leaf(root->Rchild);
}
return (leaf1+leaf2);
}
//求树的深度
int postTreeDepth(BiTree root)
{
int hr,hl,h;
if(root==NULL)
return 0;
else
{
hl=postTreeDepth(root->Lchild);
hr=postTreeDepth(root->Rchild);
h=((hr>hl)?hr:hl)+1;
return h;
}
}
//打印树 (参数分别是树根和树的深度)
void printTree(BiTree root,int h)
{
if(root==NULL)
return ;
printTree(root->Rchild,h+1);
for(int j=0;j<h+1;j++)
{
printf("-");
}
printf("%c\n",root->data);
printTree(root->Lchild,h+1);
}
//某一层k的叶子结点个数(待修改)
int * count_leaf_Level(BiTree root,int k)
{
BiTree QCountPoint[100];
BiTree bt;
bt=root;
int front,rear;
int point[2]={0,0},last,level;
front=rear=0;
if(bt==NULL||k<=1)
return 0;
rear++;
QCountPoint[rear]=bt;
last=rear;
level=1;
while(rear!=front)
{
front=front+1;
bt=QCountPoint[front];
if(level==k&&bt->Lchild==NULL&&bt->Rchild==NULL)
point[0]++;
if(level==k)
point[1]++;
if(bt->Lchild!=NULL)
{
rear=rear+1;
QCountPoint[rear]=bt->Lchild;
}
if(bt->Rchild!=NULL)
{
rear=rear+1;
QCountPoint[rear]=bt->Rchild;
}
if(front==last)
{
level++;
last=rear;
}
if(level>k)
return point;
}
}
//统计每一层的叶子节点个数
void print_count_leaf(BiTree root)
{
int j;
int *p;
point.depth=postTreeDepth(root);
for(j=1;j<point.depth;j++)
{
p=count_leaf_Level(root,j);
point.countleaf[j]=*p;
point.countpoint[j]=*(p+1);
}
}
//二叉树的繁茂度
int Lush_degree(BiTree root)
{
int max=0;
for(int j=1;j<point.depth;j++)
{
if(max<point.countpoint[j])
max=point.countpoint[j];
}
return (max*postTreeDepth(root));
}
//判定是否为完全二叉树
int IsComBinTree(BiTree root)
{
int depthL,depthR,j;
depthL=postTreeDepth(root->Lchild)+1;
depthR=postTreeDepth(root->Rchild)+1;
if((depthL==depthR)||(depthL-depthR==1))
{
for( j=1;j<=point.depth-2;j++)
{
if(point.countleaf[j]!=0)
break;
}
if(j==(point.depth-2))
return TRUE;
else
return FALSE;
}
else
return FALSE;
}
/************访问函数*****************/
void visit(char ch)
{
putchar(ch);
printf(" ");
}
二叉树的应用(二叉树)
[问题描述]
编程实现二叉树的建立,先序、中序、后序(递归和非递归方法)、层序遍历,二叉树的高度、繁茂度,
交换左右子树,统计叶子节点的数目,判断是否为完全二叉树,按树的形态在屏幕上打印输出。
[基本要求]
(1) 从文件中读入建树信息,树的节点数目不小于20个,树的高度不小于4。
(2) 建树信息采用两行英文字符表示,每个英文字符代表一个结点,第1行为树的中序遍历结果,
第2行为树的后序遍历结果。
[名词注释]
二叉树的繁茂度:为各层结点数的最大值与树的高度的乘积
完全二叉树:
a:所有节点只可能出现在最大的两层上
b:对于任何节点,若其右子树的层高为k,则其左子树可能为k或者是k+1
注意:该程序是在vc++6.0中运行成功,同时需要安装easyx插件才能正常运行,实现图形界面
测试数据:ABD##EF###C#GHJ#K###I##
*/
#include <stdio.h>
#include <malloc.h>
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
//树型结构体
typedef struct Node
{
char data;
struct Node *Lchild;
struct Node *Rchild;
}BiTNode,*BiTree;
//栈元素结构体
typedef struct node
{
BiTree tree;
struct node *next;
}seqstack,*stack;
//队列元素结构体
typedef struct node1
{
BiTree tree;
struct node1 *next;
} Qnode;
//队列的队头和队尾元素指针
typedef struct
{
Qnode *front;
Qnode *rear;
}LQnode;
//用于统计每一层叶子节点个数
typedef struct
{
int countleaf[10];
int countpoint[10];
int depth;
}countPoint;
/*typedef struct
{
char mid[100];
char post[100];
}tree; */
countPoint point;
//用于统计节点数的全局变量
int count1=0,count2=0;
//用于寻根函数
BiTree tree[100];
int i=0;
//tree list;//定义存储树序列的全局变量
stack init_seq();//初始化空栈,创建站顶元素,返回栈顶指针
int isempty(stack sq);//置栈空
void push(stack sq,BiTree tr);//进栈
void pop(stack sq,BiTree *p);//出栈
BiTree top(stack sq);//取栈顶数据
LQnode *init_LQnode();
int isempty_L(LQnode *q);
void in_LQnode(LQnode *q,BiTree tr);
void out_LQnode(LQnode *q,BiTree *tr);
void creat_Btree(BiTree *root,FILE *fp);//创建树
void pre_visit(BiTree root);//非递归先序遍历
void re_pro_visit(BiTree root);//递归先序遍历
void mid_visit(BiTree root);//非递归中序遍历
void re_mid_visit(BiTree root);//递归中序遍历
void post_visit(BiTree root);//非递归先后序遍历
void re_post_visit(BiTree root);//递归先后序遍历
void leval_visit(BiTree root);//层次遍历
BiTree parent (BiTree root,BiTree leaf);//搜索双亲函数
void print_path(BiTree root);//打印路径函数
void swap_tree(BiTree root);//交换左右子树
void post_visit_point(BiTree root);//递归统计有两个孩子节点和至少有一个孩子的节点,间接统计只有一个孩子的节点
int mid_visit_leaf(BiTree root);//输出叶子节点个数和叶子节点
void pro_visit_leaf(BiTree root);//先序统计叶子节点
int postTreeDepth(BiTree root);//求树的深度
void printTree(BiTree root,int h);//打印树
int * count_leaf_Level(BiTree root,int k);//某一层k的叶子结点个数(待修改)
void print_count_leaf(BiTree root); //统计每一层的叶子节点个数
int Lush_degree(BiTree root);//二叉树的繁茂度
int IsComBinTree(BiTree root);//判定是否为完全二叉树
FILE * file();
void visit(char ch);
int main ()
{
system("title 树操作系统 ");
int leaf,depth;//叶子节点数和树的深度
FILE *fp;
BiTree root;
fp=FILE * file();
creat_Btree(&root,fp);//创建树
return 0;
}
/**********************界面操作*********************/
void main_menu()
{
int choice,choice1;
printf("\n\n\n\n");
printf("\n\t\t************欢迎进入树操作系统***********\n");
printf("\t\t \n");
printf("\t\t\t 1、遍历树\n");
printf("\t\t\t 2、交换左右子树\n");
printf("\t\t\t 3、输出叶子节点个数和叶子节点\n");
printf("\t\t\t 4、树的深度 \n");
printf("\t\t\t 5、统计每一层的叶子节点个数 \n");
printf("\t\t\t 6、判定是否为完全二叉树 \n");
printf("\t\t\t 7、二叉树的繁茂度 \n");
printf("\n\t\t************谢谢使用树操作系统***********\n");
InputBox(ch, 100, "请输入您的选择" );
sscanf(ch,"%d",&choice);
switch(choice)
{
case 1:{
system(cls);
printf("\n\n\n\n");
printf("\n\t\t************欢迎进入树操作系统***********\n");
printf("\t\t \n");
printf("\t\t\t 1、层次遍历\n");
printf("\t\t\t 2、非递归先序遍历\n");
printf("\t\t\t 3、递归先序遍历\n");
printf("\t\t\t 4、非递归中序遍历 \n");
printf("\t\t\t 5、递归中序遍历 \n");
printf("\t\t\t 6、非递归后序遍历 \n");
printf("\t\t\t 7、递归后序遍历 \n");
printf("\n\t\t************谢谢使用树操作系统***********\n");
InputBox(ch, 100, "请输入您的选择" );
sscanf(ch,"%d",&choice1);
break;
}
case 2:{swap_tree(root);break;}
case 3:{mid_visit_leaf(root);break;}
case 4:{postTreeDepth(BiTree root);;break;}
}
}
/********************栈操作 ***********************/
//初始化空栈,创建站顶元素,返回栈顶指针
stack init_seq()
{
stack sq;
sq=(stack)malloc(sizeof(seqstack));
sq->next=NULL;
return sq;
}
//置栈空
int isempty(stack sq)
{
if(sq->next==NULL)
return 1;
return 0;
}
//入栈函数
void push(stack sq,BiTree tr)
{
stack q;
q=(stack)malloc(sizeof(seqstack));
q->tree=tr;
q->next=sq->next;
sq->next=q;
// free(q);
}
//出栈函数
void pop(stack sq,BiTree *p)
{
// char *ch;
stack q;
q=sq->next;
sq->next=q->next;
(*p)=q->tree;
free(q);
}
//取栈顶元素
BiTree top(stack sq)
{
BiTree p;
if(!isempty(sq))
{
p=sq->next->tree;
}
return p;
}
/**********************队列操作*******************/
//初始化队列
LQnode *init_LQnode()
{
LQnode *q;
Qnode *p;
q=(LQnode*)malloc(sizeof(LQnode));
p=(Qnode*)malloc(sizeof(Qnode));
p->next=NULL;
q->front=q->rear=p;
return q;
}
int isempty_L(LQnode *q)
{
if(q->front==q->rear)
return 1;
else
return 0;
}
//入队
void in_LQnode(LQnode *q,BiTree tr)
{
Qnode *p;
p=(Qnode*)malloc(sizeof(Qnode));
p->tree=tr;
p->next=NULL;
q->rear->next=p;
q->rear=p;
}
//出队
void out_LQnode(LQnode *q,BiTree *tr)
{
if(!isempty_L(q))
{
Qnode *p;
p=(Qnode*)malloc(sizeof(Qnode));
p=q->front->next;
q->front->next=p->next;
*tr=p->tree;
free(p);
if(q->front->next==NULL)
q->rear=q->front;
}
}
/****************文件操作********************/
//打开文件操作
FILE * file()
{
FILE *fp;
char filename[]="树.txt";
fp=fopen(filename,"r");
if(fp==NULL)
{
printf("\n 打开文件失败,%s可能不存在,请先到对应文件夹下建立该文件!\n",filename);
exit(1);
}
return fp;
}
/********************文件操作**********************/
/********************二叉树操作**********************/
//扩展先序建立二叉树
//递归一次便给当前节点的数据域赋值,然后利用递归
//一次给该结点的左右子树赋值,实现二叉树的创建
void creat_Btree(BiTree *root,FILE *fp)
{
char ch;
ch=fgetc(fp);
if(ch==EOF)
return ;
if(ch=='#')
(*root)=NULL;
else{
(*root)=(BiTree)malloc(sizeof(BiTNode));
(*root)->data=ch;
creat_Btree(&((*root)->Lchild),fp);
creat_Btree(&((*root)->Rchild),fp);
}
}
//利用中序后序遍历建立二叉树
void creat_mid_post_tree(BiTree *root)
{
}
//非递归先序遍历
/* 首先对根节点和左子树以此访问并且顺序入栈,如果当前访问节点的左子树为空,
将该节点A退栈,访问该子树的右子树,对该节点的右子树按照上述方法进行遍历访问,访问完之后退回到,
A节点的双亲节点,将其退栈,同样的方法访问其右子树,以此类推访问完整个二叉树。
*/
void pre_visit(BiTree root)
{
stack s;
BiTree p;
s=init_seq();
p=root;
while(p!=NULL||!isempty(s))
{
while(p!=NULL)
{
visit(p->data);
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
pop(s,&p);
p=p->Rchild;
}
}
}
//递归实现先序遍历
void re_pro_visit(BiTree root)
{
if(root)
{
visit(root->data);
re_pro_visit(root->Lchild);
re_pro_visit(root->Rchild);
}
}
//非递归中序遍历
/* 首先通过循环不断将节点入栈,直到找到左子树的最左侧的节点,从该节点进行遍历,先访问该结点,然后退栈,访问根节点,
再然后进入该根节点的右子树,同样的方法进行访问,访问完之后,将该根节点的根节点退栈,同样的方法访问他的右子树,一直循环直至
栈为空且,辅助指针为空,表示二叉树访问完
*/
void mid_visit(BiTree root)
{
stack s;
BiTree p;
s=init_seq();
p=root;
while(p!=NULL||!isempty(s))
{
while(p!=NULL)
{
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
pop(s,&p);
visit(p->data);
p=p->Rchild;
}
}
}
//递归实现中序遍历
void re_mid_visit(BiTree root)
{
if(root)
{
re_mid_visit(root->Lchild);
visit(root->data);
re_mid_visit(root->Rchild);
}
}
//非递归后序遍历
/* 首先通过循环不断将节点入栈,直到找到左子树的最左侧的节点,然后取栈顶元素,即该结点,及对其右子树进行考察,
如果其右子树是空或者是已经访问过,则退栈,访问站顶元素,并将其地址赋值给第二辅助标记指针变量,并将第一指
针变量置为空,便于再退栈,访问下一个节点的数据,否则如果该节点的右子树不为空且未被访问过,则同样的访问该节点的右子树。
*/
void post_visit(BiTree root)
{
stack s;
s=init_seq();
BiTree p,q;
p=root;q=NULL;
while(!isempty(s)||p!=NULL)
{
while(p!=NULL)
{
push(s,p);
p=p->Lchild;
}
if(!isempty(s))
{
p=top(s);
if((p->Rchild==NULL)||(p->Rchild==q))
{
pop(s,&p);
visit(p->data);
q=p;
p=NULL;
}
else
p=p->Rchild;
}
}
}
//递归实现后序遍历
void re_post_visit(BiTree root)
{
if(root)
{
re_post_visit(root->Lchild);
re_post_visit(root->Rchild);
visit(root->data);
}
}
//层次遍历
void leval_visit(BiTree root)
{
LQnode *q;
q=init_LQnode();
BiTree p;
in_LQnode(q,root);
while(!isempty_L(q))
{
out_LQnode(q,&p);
visit(p->data);
if(p->Lchild!=NULL)
in_LQnode(q,p->Lchild);
if(p->Rchild!=NULL)
in_LQnode(q,p->Rchild);
}
}
/*
//主体部分分为查找叶子节点、寻找双亲函数和打印路径三部分
void pro_visit_leaf(BiTree root)
{
if(root)
{
if(root->Lchild==NULL&&root->Rchild==NULL)
{
tree[i]=root;
// visit(tree[i]->data);
i++;
}
pro_visit_leaf(root->Lchild);
pro_visit_leaf(root->Rchild);
}
}
*/
//搜索某一节点的双亲
BiTree parent (BiTree root,BiTree leaf)
{
BiTree p;
if(root==NULL)
return NULL;
if(root->Lchild==leaf||root->Rchild==leaf)
return root;
p=parent(root->Lchild,leaf);
if(p!=NULL)
return p;
else
return (parent(root->Rchild,leaf));
}
//打印某一节点到根节点的路径
void print_path(BiTree root)
{ BiTree p;
char ch[100];
int k;
for(int j=0;j<i;j++)
{
k=0;
p=tree[j];
// printf("%c:",p->data);
visit(p->data);
while(p->data!=root->data)
{
p=parent (root,p);
ch[k]=p->data;
k++;
}
while(k>=1)
{
visit(ch[k-1]);
k--;
}
printf("\n");
}
}
//交换左右子树
/*通过递归实现,原理就是将换两个变量的值*/
void swap_tree(BiTree root)
{
BiTree p;
p=root->Lchild;
root->Lchild=root->Rchild;
root->Rchild=p;
if(root->Lchild!=NULL)
swap_tree(root->Lchild);
if(root->Rchild!=NULL)
swap_tree(root->Rchild);
}
//递归统计有两个孩子节点和至少有一个孩子的节点,间接统计只有一个孩子的节点
void post_visit_point(BiTree root)
{
if(root)
{
if(root->Lchild!=NULL&&root->Rchild!=NULL)
count2++;//统计有两个孩子的节点个数
if((root->Lchild!=NULL||root->Rchild!=NULL))
count1++;//统计至少有一个孩子的节点个数
post_visit_point(root->Lchild);
post_visit_point(root->Rchild);
}
}
//输出叶子节点个数和叶子节点
int mid_visit_leaf(BiTree root)
{
int leaf1=0,leaf2=0;
if(root)
{
if(root->Lchild==NULL&&root->Rchild==NULL)
{
tree[i]=root;
i++;
visit(root->data);
return 1;
}
leaf1=mid_visit_leaf(root->Lchild);
leaf2=mid_visit_leaf(root->Rchild);
}
return (leaf1+leaf2);
}
//求树的深度
int postTreeDepth(BiTree root)
{
int hr,hl,h;
if(root==NULL)
return 0;
else
{
hl=postTreeDepth(root->Lchild);
hr=postTreeDepth(root->Rchild);
h=((hr>hl)?hr:hl)+1;
return h;
}
}
//打印树 (参数分别是树根和树的深度)
void printTree(BiTree root,int h)
{
if(root==NULL)
return ;
printTree(root->Rchild,h+1);
for(int j=0;j<h+1;j++)
{
printf("-");
}
printf("%c\n",root->data);
printTree(root->Lchild,h+1);
}
//某一层k的叶子结点个数(待修改)
int * count_leaf_Level(BiTree root,int k)
{
BiTree QCountPoint[100];
BiTree bt;
bt=root;
int front,rear;
int point[2]={0,0},last,level;
front=rear=0;
if(bt==NULL||k<=1)
return 0;
rear++;
QCountPoint[rear]=bt;
last=rear;
level=1;
while(rear!=front)
{
front=front+1;
bt=QCountPoint[front];
if(level==k&&bt->Lchild==NULL&&bt->Rchild==NULL)
point[0]++;
if(level==k)
point[1]++;
if(bt->Lchild!=NULL)
{
rear=rear+1;
QCountPoint[rear]=bt->Lchild;
}
if(bt->Rchild!=NULL)
{
rear=rear+1;
QCountPoint[rear]=bt->Rchild;
}
if(front==last)
{
level++;
last=rear;
}
if(level>k)
return point;
}
}
//统计每一层的叶子节点个数
void print_count_leaf(BiTree root)
{
int j;
int *p;
point.depth=postTreeDepth(root);
for(j=1;j<point.depth;j++)
{
p=count_leaf_Level(root,j);
point.countleaf[j]=*p;
point.countpoint[j]=*(p+1);
}
}
//二叉树的繁茂度
int Lush_degree(BiTree root)
{
int max=0;
for(int j=1;j<point.depth;j++)
{
if(max<point.countpoint[j])
max=point.countpoint[j];
}
return (max*postTreeDepth(root));
}
//判定是否为完全二叉树
int IsComBinTree(BiTree root)
{
int depthL,depthR,j;
depthL=postTreeDepth(root->Lchild)+1;
depthR=postTreeDepth(root->Rchild)+1;
if((depthL==depthR)||(depthL-depthR==1))
{
for( j=1;j<=point.depth-2;j++)
{
if(point.countleaf[j]!=0)
break;
}
if(j==(point.depth-2))
return TRUE;
else
return FALSE;
}
else
return FALSE;
}
/************访问函数*****************/
void visit(char ch)
{
putchar(ch);
printf(" ");
}