#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
typedef char ElemType; //节点元素的类型
typedef struct {
ElemType elem; //节点元素数据
bool isFull; //结点是否为满,true为满,false为空
}SqTreeNode;
typedef struct {
SqTreeNode* elems; //存放元素数据
int length; //二叉树的当前结点个数
int maxSize; //该二叉树能存放的最大结点个数
}SqTree;
//创建最大结点数为maxSize的空二叉树
SqTree* createBiTree(int maxSize){
SqTree* t = (SqTree*)malloc(sizeof(SqTree));
t->maxSize = maxSize;
t->length = 0;
t->elems = (SqTreeNode*)malloc(sizeof(SqTreeNode)*maxSize);
for(int i=0; i<maxSize; i++){
t->elems[i].isFull = false;
}
printf("输入二叉树的层序遍历序列(空结点用'#'表示,如abcdfg##e###h##):\n");
char* chars = (char*)malloc(sizeof(char)*(maxSize+1));
scanf("%s",chars);
for(int i=0; i<strlen(chars); i++){
if(chars[i] != '#'){
t->elems[i].elem = chars[i];
t->elems[i].isFull = true;
t->length += 1;
}
}
free(chars);
return t;
}
//释放二叉树的资源
void releaseBiTree(SqTree* t){
free(t->elems);
free(t);
}
//层序遍历
void floorTravel(SqTree* t){
for(int i=0; i<t->maxSize; i++){
if(t->elems[i].isFull == true){
printf("%c", t->elems[i].elem);
}
}
}
//先序遍历
//打印结点信息
void visit(SqTreeNode node){
printf("%c",node.elem);
}
void preOrderLoop(SqTree* t, int index){
if(index < t->maxSize && t->elems[index].isFull == true){
visit(t->elems[index]);
preOrderLoop(t, index*2+1);
preOrderLoop(t, index*2+2);
}
}
void preOrder(SqTree* t){
preOrderLoop(t, 0);
}
//中序遍历
void inOrderLoop(SqTree* t, int index){
if(index < t->maxSize && t->elems[index].isFull == true){
inOrderLoop(t, index*2+1);
visit(t->elems[index]);
inOrderLoop(t, index*2+2);
}
}
void inOrder(SqTree* t){
inOrderLoop(t, 0);
}
//后序遍历
void postOrderLoop(SqTree* t, int index){
if(index < t->maxSize && t->elems[index].isFull == true){
postOrderLoop(t, index*2+1);
postOrderLoop(t, index*2+2);
visit(t->elems[index]);
}
}
void postOrder(SqTree* t){
postOrderLoop(t, 0);
}
//求结点个数
int length(SqTree* t){
return t->length;
}
//求叶子结点个数
int lengthLeaf(SqTree* t){
int count = 0;
for(int i=0; i<t->maxSize; i++){
if(t->elems[i].isFull == true &&
(i*2+1 >= t->maxSize || t->elems[i*2+1].isFull == false) &&
(i*2+2 >= t->maxSize || t->elems[i*2+2].isFull == false)){
count += 1;
}
}
return count;
}
//求二叉树的度为1的结点个数
int lengthDegree1(SqTree* t){
int count = 0;
for(int i=0; i<t->maxSize; i++){
if(t->elems[i].isFull == true && (
(((i*2+1)<t->maxSize && t->elems[i*2+1].isFull == true) && ((i*2+2) >= t->maxSize || t->elems[i*2+2].isFull == false)) ||
(((i*2+2)<t->maxSize && t->elems[i*2+2].isFull == true) && ((i*2+1) >= t->maxSize || t->elems[i*2+1].isFull == false)))){
count += 1;
}
}
return count;
}
//求二叉树的深度
int depth(SqTree* t){
int index = -1;
for(int i=t->maxSize-1; i>=0; i--){
if(t->elems[i].isFull == true){
index = i;
break;
}
}
index ++;
int depth = -1;
do{
depth ++;
}while(index >= pow(2.0,depth*1.0));
return depth;
}
//输出二叉树中从每个叶子结点到根结点的路径
void printLeafPath(SqTree* t){
//先判断是否是叶子结点
for(int i=0; i<t->maxSize; i++){
if(t->elems[i].isFull == true &&
(i*2+1 >= t->maxSize || t->elems[i*2+1].isFull == false) &&
(i*2+2 >= t->maxSize || t->elems[i*2+2].isFull == false)){
//打印这个结点的路径
int index = i+1;
printf("%c: ",t->elems[i].elem);
while(index != 0){
visit(t->elems[index-1]);
index /= 2;
}
printf("\n");
}
}
}
int main(){
//创建一个二叉树(层序遍历)
SqTree* t = createBiTree(100);
//层序遍历
printf("层序遍历:"); floorTravel(t); printf("\n");
//前序遍历
printf("前序遍历:"); preOrder(t); printf("\n");
//中序遍历
printf("中序遍历:"); inOrder(t); printf("\n");
//后序遍历
printf("后序遍历:"); postOrder(t); printf("\n");
//二叉树的深度
printf("二叉树的深度:%d\n", depth(t));
//二叉树的结点个数
printf("二叉树的结点个数:%d\n", length(t));
//二叉树的叶子结点个数
printf("二叉树的叶子结点个数:%d\n", lengthLeaf(t));
//二叉树的度为1的结点个数
printf("二叉树的度为1的结点个数:%d\n",lengthDegree1(t));
//输出二叉树中从每个叶子结点到根结点的路径
printf("输出二叉树中从每个叶子结点到根结点的路径:\n"); printLeafPath(t);
releaseBiTree(t);
return 0;
}
结果:
输入二叉树的层序遍历序列(空结点用'#'表示,如abcdfg##e###h##):
abcdfg##e###h##
层序遍历:abcdfgeh
前序遍历:abdefcgh
中序遍历:debfaghc
后序遍历:edfbhgca
二叉树的深度:4
二叉树的结点个数:8
二叉树的叶子结点个数:3
二叉树的度为1的结点个数:3
输出二叉树中从每个叶子结点到根结点的路径:
f: fba
e: edba
h: hgca