本来想做纯二叉树的遍历的,但是做的时候感觉加上哈夫曼编码的建立规则吧,于是这个四不像便产生啦。。。
不过基本的三种遍历方法还在。求节点数,树的深度,二叉树每层节点数也有的。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int Count = 0; /*统计二叉树节点*/
int Depth = 0; /*二叉树的深度*/
/*二叉树结构*/
typedef struct BNode
{
char data; /*字符*/
int weight; /*出现次数,即权重*/
struct BNode *left,*right; /*左子女,右子女*/
}BTNode,*BTree;
/*字符和出现频率的映射表*/
typedef struct
{
char data; /*字符*/
int weight; /*出现次数,即权重*/
int level; /*该字符所在二叉树层次*/
}chart;
/*创建字符和频率映射表*/
chart * CreateChart()
{
int i;
chart *List = (chart *)malloc(sizeof(chart) * Count); /*动态分配有NUM个chart*类型单元的数组*/
/*循环方式建立List表*/
for (i = 0 ; i < Count ; i++)
{
printf("Please enter the character of NO%d.:\n",i+1); /*输入字符*/
fflush(stdin);
scanf("%c",&List[i].data);
fflush(stdin);
printf("Please enter the weight of NO%d.:\n",i+1); /*输入权重*/
scanf("%d",&List[i].weight);
List[i].level = 0;
}
return List;
}
/*插入一个数据,数据左小右大*/
int Insert(BTree root,char Data,int weight)
{
int level = 1; /*level代表该节点插入的层次*/
BTree temp,father,child; /*temp是临时结点,father是对比结点的父结点,child是当前对比结点。*/
/*创建临时结点*/
temp = (BTree)malloc(sizeof(BTNode));
temp->data = Data;
temp->weight = weight;
temp->left = NULL;
temp->right = NULL;
child = root;
/*该临时结点的挂链*/
while (child)
{
father = child;
if (child->weight > temp->weight) /*权重小的放在左边*/
child = child->left;
else /*权重大的放在右边*/
child = child->right;
level++;
}
if (father->weight > temp->weight)
father->left = temp;
else
father->right = temp;
return level;
}
/*创建二叉树*/
BTree CreateBTree(chart *List)
{
int i;
BTree root;
/*创建根节点*/
root = (BTree)malloc(sizeof(BTNode));
root->data = List[0].data;
root->weight = List[0].weight;
root->left = NULL;
root->right = NULL;
List[0].level=1;
Depth = 1;
/*创建其余节点*/
for (i=1;i<Count;i++)
{
List[i].level = Insert(root,List[i].data,List[i].weight);
if (Depth < List[i].level)
Depth = List[i].level;
}
return root;
}
/*先序遍历*/
void PreOrderTraverse(BTree root)
{
if (root)
{
printf("\t%c",root->data);
PreOrderTraverse(root->left);
PreOrderTraverse(root->right);
}
}
/*中序遍历*/
void InOrderTraverse(BTree root)
{
if(root)
{
InOrderTraverse(root->left);
printf("\t%c",root->data);
InOrderTraverse(root->right);
}
}
/*后序遍历*/
void PostOrderTraverse(BTree root)
{
if(root)
{
PostOrderTraverse(root->left);
PostOrderTraverse(root->right);
printf("\t%c",root->data);
}
}
/*统计输出二叉树每层节点数*/
void NodeNum(chart *List)
{
int i,L; /*L是每个字符所在二叉树的层数*/
int *llevel; /*llevel指向存储每层结点的数组*/
llevel= (int *)malloc(sizeof(int) * (Depth+1) ) ; /*建立一个拥有Depth+1个单元的数组,用来存储每层节点数。*/
memset(llevel, 0, sizeof(int) * (Depth+1));
/*统计每层节点数*/
for (i = 0; i < Count; i++)
{
L=List[i].level;
llevel[L]++;
}
/*输出每层节点数*/
for(i = 1; i < Depth+1; i++)
{
printf("Level %d has %d nodes.\n", i, llevel[i] );
}
}
/*主程序*/
int main(void)
{
chart *List; /*List是字符和频率的映射表*/
BTree root; /*root是二叉树的根节点*/
printf("Please enter the number of characters:\n");/*设置字符总数*/
scanf("%d",&Count);
List = CreateChart();
root = CreateBTree(List);/*创建二叉树*/
system("cls");
/*先序输出*/
printf("\n先序输出\n");
PreOrderTraverse(root);
/*中序输出*/
printf("\n中序输出\n");
InOrderTraverse(root);
/*后序输出*/
printf("\n后序输出\n");
PostOrderTraverse(root);
/*输出二叉树节点总数*/
printf("\nThe number of nodes of binary tree is: %d.\n",Count);
/*统计并输出该二叉树的深度*/
printf("\nThe number of level of binary tree is: %d\n",Depth);
/*输出每层有几个节点*/
NodeNum(List);
return 0;
}