/*江江制作,邮箱 flysky2011@163.com,多多交流*/
#include <stdio.h>
#define Max 20 //最多数据的数据个数
/*存放数据的结构单元*/
struct node{
float data;//输入的数据值
int parent,leftKid,rightKid;//数据的父亲,左孩子,右孩子,并且左孩子<右孩子
}Huf[Max+Max-1];
int number;//输入数据的个数
float firstMin ,secondMin ;
/*提示信息*/
void showInf(){
printf("请输入数据,并以-1做结束符(如果要数据2 1 3,则输入的格式为 2 1 3 -1)/n");
}
/* 输入数据,并用number记住输入的数据的个数*/
void inputData(){
float num;
int i=0;
number=0;//初始化为0
scanf("%f",&num);
while(num !=-1.0){
Huf[i].data = num;
Huf[i].parent = -1;
Huf[i].leftKid = -1;
Huf[i].rightKid = -1;
i++;
number++;
scanf("%f",&num);
}
}
/*在哈弗曼结构体中寻找最小的两个数据,并找到这两个孩子的父亲*/
search(){
int i,k,first_locate,second_locate;//first_locate为第一个孩子的所在位置,second_locate为第二个
孩子所在的位置
firstMin=65536;//2的16次方,默认最大
secondMin=65536;//2的16次方,默认最大
/*找出输入数据中的第一个孩子,并不是最小的孩子*/
for(i=0; i<number;i++){
if(Huf[i].parent==-1){
if(Huf[i].data<firstMin){
firstMin=Huf[i].data;
first_locate = i;
break;//找到一个就结束
}
}
}
/*找出输入数据中的第二个孩子,并不是次小的孩子*/
for(k=0; k<number;k++){
if(Huf[k].parent==-1&&k!=first_locate){//search the second child
if(Huf[k].data<secondMin){
secondMin=Huf[k].data;
second_locate = k;
break;//找到一个就结束
}
}
}
/*如果第一个孩子>第二个孩子就交换第一和第二个孩子,并把他们相应的位置也交换*/
if(firstMin>=secondMin){
i = secondMin;
secondMin = firstMin;
firstMin = i;
i=first_locate;
first_locate = second_locate;
second_locate = i;
}
/* 找到当前最小的两个孩子,firstMin < secondMin*/
for(k=0;k<number;k++){
if(Huf[k].parent ==-1&&(k!=first_locate)&&(k!=second_locate)){//当前数据没有父
亲,并且不等于初始化默认的两个孩子的位置
if(Huf[k].data <secondMin ){//当前数据<secondMin
if( Huf[k].data >firstMin){//当firstMin < 当前数据 < secondMin
时,把当前数据置为第二个孩子
secondMin = Huf[k].data;
second_locate = k;
}
else{ //当 当前数据< firstMin时,把当前数据置为第一个孩子
secondMin = firstMin;
second_locate = first_locate;
firstMin = Huf[k].data;
first_locate = k;
}
}
}
}
Huf[number].data = firstMin + secondMin;//两个孩子父亲的值
Huf[number].parent=-1;//两个孩子父亲的父亲为空
Huf[first_locate].parent = number;//第一个孩子找到父亲为number
Huf[second_locate].parent = number;//第二个孩子找到父亲为number
Huf[number].leftKid = first_locate;//父亲的左孩子为first_locate
Huf[number].rightKid = second_locate;//父亲的右孩子为second_locate
number++;//数据位加一
}
/*打印数据的路径,从孩子向父亲打印*/
show(){
int i,k;
for(i=0;i<number;i++){//数据路径中的数据值
if(Huf[i].rightKid==-1){
k=i;
printf("data=%.1f的路径值: ",Huf[i].data);
while(Huf[k].parent!=-1){
printf("%.1f ",Huf[k].data);
k=Huf[k].parent;
}
printf("%.1f /n",Huf[k].data);
}
}
printf("/n");
for(i=0;i<number;i++){//输出路径,0为左孩子,1为右孩子
if(Huf[i].rightKid==-1){
k=i;
printf("data=%.1f的路径(0为左孩子,1为右孩子): ",Huf[i].data);
while(Huf[k].parent!=-1){
if(k == Huf[Huf[k].parent].leftKid)
printf("0 ");
else
printf("1 ");
k=Huf[k].parent;
}
printf("/n");
}
}
}
judge(){
}
/*主函数*/
void main(){
int count;
char ch='y';
while(ch=='y'){//是否继续测试
showInf();
inputData();
count =number;
if(number==1){
printf("提示信息: 至少数据两个正数/n/n");
continue;
}
if(number>Max){
printf("/n输入数据过多,当前最多可以输入%d位数据。可以修改程序开头的Max值来扩展
数据的位数/n/n",Max);
continue;
}
while(number!=2*count-1)
search();
printf("/n");
show();
printf("/n");
printf("是否继续测试 :y , n/n");
getchar();//接收数据数据时按下的回车
scanf("%c",&ch);
}
}
/*自己写的,希望多多支持,严禁篡改!*/