用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - c++代码库

哈夫曼算法 c++

2013-03-08 作者: 神马举报

[c++]代码库

#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>

/*声明两种链表结构----start*/
struct node_a { /*链表1-----作用:用来统计文件中字符的个数和种类(通过count)*/
	char data;
	int count;
	struct node_a *next;
};
typedef struct node_a node,*list;
list head=NULL;

struct nodeb { /*链表2-----作用:用来建立用相应的编码代替字符的新文件*/
	char data;
	struct nodeb *next;
};
typedef struct nodeb node_b,*list_b;  /*jiang bianma xieru wenjian*/
list_b head_b=NULL;
/*声明两种链表结构----end*/

/*哈夫曼算法种相关的3种结构的声明-----start*/
struct forest {
	float weight;
	int root;
};
struct alphabet {
	char symbol;
	float probability;
	int leaf;
	char *bianma;
};
struct tree {
	int lchild;
	int rchild;
	int parent;
};
typedef struct tree *tree_ptr,tree_node;
typedef struct forest *forest_ptr,forest_node;
typedef struct alphabet *alphabet_ptr,alphabet_node;
tree_ptr tree1;
forest_ptr forest1;
alphabet_ptr alphabet1;
int lasttree,lastnode;
int least,second;
/*哈夫曼算法种相关的3种结构的声明-----end*/

/**************stack difination start****************/
struct stacknode {
	char *bian_ma;
	struct stacknode *next;
};
typedef struct stacknode stack_node;
typedef stack_node *link;
link top=NULL;

void push ( char *item ) {
	link p;
	if ( top!=NULL ) {
		p= ( link ) malloc ( sizeof ( stack_node ) );
		if ( p==NULL ) {
			printf ( "Memory allocation error!" );
			return;
		}
		p->bian_ma=item;
		p->next=top;
		top=p;
	} else {
		top= ( link ) malloc ( sizeof ( stack_node ) );
		if ( !top ) {
			printf ( "Memory allocation error!" );
			return;
		}
		top->bian_ma=item;
		top->next=NULL;
	}
}

void pop ( void ) {
	link p;
	p=top;
	top=top->next;
	free ( p );
}

void makenull ( void ) {
	while ( top!=NULL )
		pop();
}

int empty() {
	if ( top==NULL )
		return 1;
	else
		return 0;
}

char* tops ( void ) {
	return ( top->bian_ma );
}

void display_stack ( link s ) { /*显示栈重的内容*/
	link ptr;
	ptr=s;
	while ( ptr!=NULL ) {
		printf ( "%s",ptr->bian_ma );
		ptr=ptr->next;
	}
}

/***************************stack__difination is end************************/
void display ( list h ) { /*显示链表1*/
	list ptr;
	int i=1;
	ptr=h->next;
	while ( ptr!=NULL ) {
		printf ( "%d,%c,%d\n",i,ptr->data,ptr->count );
		i++;
		ptr=ptr->next;
	}
}
void display_b ( list_b h ) {  /*显示链表2*/
	list_b ptr;
	int i=1;
	ptr=h->next;
	while ( ptr!=NULL ) {
		printf ( "%d,%c\n",i,ptr->data );
		i++;
		ptr=ptr->next;
	}
}

void insert ( char item ) {  /*用于插入元素以建立链表1*/
	list temp,ptr;
	int flag;
	ptr=head->next;
	if ( ptr==NULL ) {
		head->next= ( list ) malloc ( sizeof ( node ) );
		head->next->data=item;
		head->next->count=1;
		head->next->next=NULL;
	} else {
		while ( ptr!=NULL ) {
			if ( ptr->data==item ) {
				ptr->count=ptr->count+1;
				flag=1;
			}
			ptr=ptr->next;
		}
		ptr=head;
		if ( flag==1 )
			return;
		else {
			temp=ptr->next;
			ptr->next= ( list ) malloc ( sizeof ( node ) );
			ptr->next->data=item;
			ptr->next->count=1;
			ptr->next->next=temp;
		}
	}
}

void insert_b ( char item ) {  /*插入元素以建立链表2*/
	list_b ptr_b, temp_b;
	ptr_b=head_b;
	if ( ptr_b->next==NULL ) {
		head_b->next= ( list_b ) malloc ( sizeof ( node_b ) );
		head_b->next->data=item;
		head_b->next->next=NULL;
	} else {
		while ( ptr_b->next!=NULL ) {
			ptr_b=ptr_b->next;
		}
		ptr_b->next= ( list_b ) malloc ( sizeof ( node_b ) );
		ptr_b->next->data=item;
		ptr_b->next->next=NULL;
	}
}

void search ( void ) { /*搜索文件并将文件中的数据分别存入作用不同的链表中*/
	FILE *fp;
	list ptr;
	char ch;
	if ( ( fp=fopen ( "test.txt","r" ) ) ==NULL )
		printf ( "Reading error!\n" );
	while ( !feof ( fp ) ) {
		ch=getc ( fp );
		if ( ferror ( fp ) ) {
			printf ( "error!\n" );
			break;
		}
		if ( ch==EOF )
			break;
		insert ( ch );   /*插入元素进链表1*/
		insert_b ( ch ); /*插入元素进链表2*/
	}
	printf ( "\n" );
	fclose ( fp );
}

void display_struct ( int n ) { /*显示哈夫曼算法中的3个结构树组 */
	int i=0;
	printf ( "\n\n=======================================\n\n" );
	printf ( "FOREST_STRUCT_ARRY :\n\n\n" );
	for ( i=0; i<=n; i++ ) {
		printf ( "%f,%d\n",forest1[i].weight,forest1[i].root );
	}
	getch();
	printf ( "\n\nALPHABET_STRUCT_ARRY :\n\n\n" );
	for ( i=0; i<=n; i++ ) {
		printf ( "%f,%d,%c\n",alphabet1[i].probability,alphabet1[i].leaf,alphabet1[i].symbol );
	}
	getch();
	printf ( "\n\nTREE_STRUCT_ARRY :\n\n\n" );
	for ( i=0; i<=2*n-1; i++ )
		printf ( "%d,%d,%d\n",tree1[i].lchild,tree1[i].rchild,tree1[i].parent );
	printf ( "\n\n======================================\n\n" );
	getch();
}

int init_struct ( void ) {  /*初始化哈夫曼算法中3种结构数组*/
	list ptr;
	float count=.0;
	int i=1,n=0;
	ptr=head->next;
	while ( ptr!=NULL ) {
		count=ptr->count+count;
		n++;
		ptr=ptr->next;
	}
	ptr=head->next;
	forest1= ( forest_ptr ) malloc ( sizeof ( forest_node ) *n+sizeof ( forest_node ) );
	alphabet1= ( alphabet_ptr ) malloc ( sizeof ( alphabet_node ) *n+sizeof ( alphabet_node ) );
	tree1= ( tree_ptr ) malloc ( sizeof ( tree_node ) *n*2-sizeof ( tree_node ) );
	forest1[0].weight=alphabet1[0].probability=0.0;
	forest1[0].root=alphabet1[0].leaf=0;
	alphabet1[0].symbol='0';
	while ( ptr!=NULL ) {
		forest1[i].weight=alphabet1[i].probability=ptr->count/count;
		forest1[i].root=alphabet1[i].leaf=i;
		alphabet1[i].symbol=ptr->data;
		i++;
		ptr=ptr->next;
	}
	for ( i=0; i<=2*n-1; i++ ) {
		tree1[i].lchild=0;
		tree1[i].rchild=0;
		tree1[i].parent=0;
	}
	return n;
}

void creat ( void ) {  /*创建正文文件test.txt*/
	FILE *fp,*out;
	char ch;
	if ( ( fp=fopen ( "test.txt","r++" ) ) ==NULL )
		printf ( "Creat error!\n" );
	printf ( "Input the data:\n" );
	ch=getch();
	putch ( ch );
	while ( ch!='#' ) {
		putc ( ch,fp );
		ch=getch();
		putch ( ch );
	}
	fclose ( fp );
}

void creat_bianma ( int number ) {  /*根据哈夫曼算法建立文件中各种字符对应的编码*/
	int i,j,n;
	int p;
	char *bm=malloc ( sizeof ( char ) *number );
	for ( n=1; n<=number; n++ ) {
		j=i=n;
		makenull();
		p=tree1[i].parent;
		while ( tree1[p].parent!=0 ) {
			if ( tree1[p].lchild==i )
				push ( "0" );
			else
				push ( "1" );
			i=p;
			p=tree1[p].parent;
		}

		if ( tree1[p].lchild==i )
			push ( "0" );
		else
			push ( "1" );
		strcpy ( bm," " ); /*目的:使创建编码文件中的各编码中间存在间隔*/
		while ( !empty() ) {
			strcat ( bm,tops() );
			pop();
		}
		alphabet1[j].bianma=malloc ( sizeof ( char ) *number );
		strcpy ( alphabet1[j].bianma,bm );
		printf ( "\n%c:%s",alphabet1[j].symbol,alphabet1[j].bianma ); /*打印出相应的编码*/
		getch();
	}
}


void write_new_file ( int number ) { /*根据相应的编码重新建立编码文件*/
	FILE *fp;
	list_b ptr;
	int i;
	char *ch=malloc ( sizeof ( char ) *number );
	ptr=head_b->next;
	if ( ( fp=fopen ( "bianma.txt","w" ) ) ==NULL )
		printf ( "Write in a new file error!" );
	else {
		while ( ptr!=NULL ) {
			for ( i=1; i<=number; i++ ) {
				if ( ptr->data==alphabet1[i].symbol ) {
					strcpy ( ch,alphabet1[i].bianma );
					fputs ( ch,fp );
				}
			}
			ptr=ptr->next;
		}
	}
	fclose ( fp );
}


void main ( void ) {
	int i,num;
	char ch;
	void huffman ( void );
	void lightones();
	head= ( list ) malloc ( sizeof ( node ) );
	head->next=NULL;
	head->data='\0';
	head->count=0;
	head_b= ( list_b ) malloc ( sizeof ( node_b ) );
	head_b->data='\0';
	head_b->next=NULL;
	do {
		system ( "cls" );
		creat();
		search();
		printf ( "\nlianbiao1:\n" );
		display ( head );/*显示链表1*/
		getch();
		printf ( "\nlianbiao2:\n" );
		display_b ( head_b );
		getch();
		num=init_struct();
		printf ( "\n" );
		printf ( "The 3 init_struct of huffman?\n" );
		display_struct ( num );/*显示初始化的哈夫曼书的相关3个结构数组*/
		lastnode=num;
		lasttree=num;
		huffman();
		printf ( "Now the 3 struct through huffman shuanfa\n" );
		display_struct ( num );/*显示哈夫曼树中相关的3种结构(经过哈夫曼算法处理)*/
		printf ( "\nThe bian_ma is:\n" );
		creat_bianma ( num );
		write_new_file ( num );
		printf ( "\nDo you want to re_try(y/n)?" );
		ch=getchar();
	} while ( ch=='y' );
}

/*哈夫曼算法-----defination_start*/
void lightones ( void ) {
	int i;
	if ( forest1[1].weight<=forest1[2].weight ) {
		least=1;
		second=2;
	} else {
		least=2;
		second=1;
	}
	for ( i=3; i<=lasttree; i++ )
		if ( forest1[i].weight<forest1[least].weight ) {
			second=least;
			least=i;
		} else if ( forest1[i].weight<forest1[second].weight )
			second=i;
}

int creat_tree ( int lefttree,int righttree ) {
	lastnode=lastnode+1;
	tree1[lastnode].lchild=forest1[lefttree].root;
	tree1[lastnode].rchild=forest1[righttree].root;
	tree1[lastnode].parent=0;
	tree1[forest1[lefttree].root].parent=lastnode;
	tree1[forest1[righttree].root].parent=lastnode;
	return ( lastnode );
}

void huffman ( void ) {
	int i,j;
	int newroot;
	while ( lasttree>1 ) {
		lightones();
		i=least;
		j=second;
		newroot=creat_tree ( i,j );
		forest1[i].weight=forest1[i].weight+forest1[j].weight;
		forest1[i].root=newroot;
		forest1[j]=forest1[lasttree];
		lasttree=lasttree-1;
	}
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...