二叉树建立及遍历

本来想做纯二叉树的遍历的,但是做的时候感觉加上哈夫曼编码的建立规则吧,于是这个四不像便产生啦。。。
不过基本的三种遍历方法还在。求节点数,树的深度,二叉树每层节点数也有的。
#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;
}



  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值