您的位置:首页 > 理论基础 > 数据结构算法

数据结构课程设计-二叉树操作系统

2015-01-01 13:06 519 查看
二叉树操作系统(哈夫曼树)头文件部分:
int a[1000];
BTree CreateHuf(ElemType a[],int n)      //根据数组a中n 个权值建立一棵哈夫曼树,返回树根指针
{
int i,j;
BTree *t1,t2;
t1=(BTree *)malloc(n*sizeof(BTree));      //二级指针
/*	for(i=0;i<n;i++)
t1[i]=(BTree)malloc(sizeof(BTNode));*/
for(i=0;i<n;i++)            //初始化t1指针数组,构建n棵只含有根节点的树
{
t1[i]=(BTree)malloc(sizeof(BTNode));
t1[i]->ans=a[i];      //n个叶子节点的权重
t1[i]->lchild=NULL;
t1[i]->rchild=NULL;    //各个叶子节点的初始化操作
}
for(i=1;i<n;i++)      //向上取n-1次父亲节点,模拟哈夫曼树的过程就知道了
{
int First_min=-1,Second_min;           //c表示森林中权值最小的根节点的下标,d表示权值第二小的根节点的下标
for(j=0;j<n;j++)           //让c,d分别指向森林中的第一棵树和第二棵树
{
if(t1[j]!=NULL&&First_min==-1)
{              //t1[j]不到数组的尾部不可能是空指针
First_min=j;
continue;  //即第一次后就有c!=-1了
}
if(t1[j]!=NULL)
{
Second_min=j;
break;      //注意break
}
}
for(j=Second_min;j<n;j++)          //从森林中找出权值最小的两棵树
{
if(t1[j]!=NULL)
{
if(t1[j]->ans<t1[First_min]->ans)
{
Second_min=First_min;
First_min=j;
}
else if(t1[j]->ans<t1[Second_min]->ans)
Second_min=j;
}
}
t2=(BTree)malloc(sizeof(BTNode));       //将找出的两棵树合并成一棵树
t2->ans=t1[First_min]->ans+t1[Second_min]->ans;
t2->lchild=t1[First_min];          //左孩子存放最小的能够一定程度上是最优二叉树是唯一的
t2->rchild=t1[Second_min];
t1[First_min]=t2;
t1[Second_min]=NULL;
}
free(t1);
return t2;             //返回整个哈夫曼树的树根
}

void Print_BTree(BTree root)
{
if(root!=NULL)
{
printf("%d", root->ans);            //输出根结点的值
if(root->lchild!=NULL||root->rchild!=NULL)
{
printf("(");
Print_BTree(root->lchild);          //输出左子树
if(root->rchild!=NULL)
printf(",");
Print_BTree(root->rchild);   //输出右子树
printf(")");
}
}
}

void Hufcoding(BTree root,int len,FILE *fp,FILE *fp2)  //编码
{
static int c[10];     //如果我这里不加static那么这里就是自动局部变量,每次递归到这里后又重新分配内存空间大小
int i;
if(root!=NULL)         //树不为空
{
if(root->lchild==NULL&&root->rchild==NULL)       //为叶子节点就打印出来
{
fprintf(fp,"%d\n",root->ans);
for(i=0;i<len;i++)
{
fprintf(fp,"%d",c[i]);
fprintf(fp2,"%d",c[i]);
}
fprintf(fp,"%c",'\n');
}
else             //访问到非叶子结点时分别向左右子树递归调用,并把分支上的0、1编码保存到数组a
{
c[len]=0;
Hufcoding(root->lchild,len+1,fp,fp2);
c[len]=1;           //c[]是标记数组吗
Hufcoding(root->rchild,len+1,fp,fp2);
}
}
}

void Decoding_HuffumanTree(BTree root,FILE *fp1)   //根据哈夫曼树的结构+编码序列得出译码序列
{
FILE *fp3;
if((fp1=fopen("coding.txt","r"))==NULL)       //编码文件
{
printf("编码文件打开失败,请检查错误.\n");
return ;
}
if((fp3=fopen("Decoding.txt","w+"))==NULL)    //译码文件
{
printf("译码文件创建失败,请检查错误.\n");
return ;
}
char *q=NULL;
BTree head=root;
q=(char *)malloc(sizeof(char));           //一颗哈夫曼树总共有2*n-1个节点
for(*q=fgetc(fp1);!feof(fp1);)        //以字符方式进行文件读写操作
{
printf("%c",*q);
*q=fgetc(fp1);     //fgetc()是每再进行一次读操作时才会自动移指针指向
}
rewind(fp1);
*q=fgetc(fp1);
while(head)
{
if(feof(fp1))
break;
if(*q=='0')
head=head->lchild;
if(*q=='1')
head=head->rchild;
if((NULL==head->lchild)&&(NULL==head->rchild))
{
fprintf(fp3,"%d\n",head->ans);
head=root;
}
*q=fgetc(fp1);
}
fclose(fp1);
fclose(fp3);
}

void Fuction_HuffumanTree(BTree root)
{
int chioce,n,i;
system("cls");
printf("\t    最优二叉书应用             \n");
printf("\t     1. 初始操作               \n");
printf("\t     2. 编码操作               \n");
printf("\t     3. 译码操作               \n");
printf("\t     4. 打印操作               \n");
printf("\t     0. 退出操作               \n");
printf("请输入相应操作: \n");
scanf("%d",&chioce);
while(!(chioce>=0&&chioce<=4))
{
printf("输入有问题,请重新输入:");
scanf("%d",&chioce);
}
while(chioce!=0)
{
switch(chioce)
{
case 1:
printf("请输入叶子节点的个数: \n");
scanf("%d",&n);
printf("请输入各个叶子节点所带有的权重:\n");
for(i=0;i<n;i++)
scanf("%d",&a[i]);
root=CreateHuf(a,n);
printf("已完成最优二叉树的构建过程!!!\n");
break;
case 2:
FILE *fp,*fp2;
if((fp=fopen("123.txt","w+"))==NULL)
{
printf("文件创建错误,请检查错误后重新来过.\n");
return ;
}
if((fp2=fopen("coding.txt","w+"))==NULL)
{
printf("文件创建错误,请检查错误后重新来过.\n");
return ;
}
Hufcoding(root,0,fp,fp2);
fclose(fp);
fclose(fp2);
printf("编码结果已写入123.txt文本文件中,请查看!!!\n");
printf("编码结果已写入coding.txt文本文件中,请查看!!!\n");
break;
case 3:
Decoding_HuffumanTree(root,fp2);
printf("\n译码结果已写入Decoding.txt文本文件中,请查看!!!\n");
break;
case 4:
printf("以广义表形式打印哈夫曼树各叶子节点关系: \n");
Print_BTree(root);
printf("\n");
break;
}
printf("请继续进行相应操作:");
scanf("%d",&chioce);
}
return ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息