⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inplace.c

📁 本程序使用8种不同的方式实现了Huffman编码算法
💻 C
字号:
/*        Illustrative example of minimum-redundancy code calculation.        Program reads a file of symbol frequencies            -- one per line            -- ascending frequency            -- first line indicates upper bound on how many                     frequencies appear;        calculate the codeword lengths for a minimum-redundancy code;        print out the codeword lengths;        print out the average cost per symbol and the entropy.        The method for calculating codelengths in function        calculate_minimum_redundancy is described in         @inproceedings{mk95:wads,                author = "A. Moffat and J. Katajainen",                title = "In-place calculation of minimum-redundancy codes",                booktitle = "Proc. Workshop on Algorithms and Data Structures",                address = "Queen's University, Kingston, Ontario",                publisher = "LNCS 955, Springer-Verlag",                Month = aug,                year = 1995,                editor = "S.G. Akl and F. Dehne and J.-R. Sack",                pages = "393-402",        }        The abstract of that paper may be fetched from         http://www.cs.mu.oz.au/~alistair/abstracts/wads95.html        A revised version is currently being prepared.        Written by		Alistair Moffat, alistair@cs.mu.oz.au,		Jyrki Katajainen, jyrki@diku.dk	November 1996.*/#include <stdio.h>#include <stdlib.h>#include <math.h>#define log2(x) (log10((double)(x))/log10(2.0))voidcalculate_minimum_redundancy(int *, int);#define LIMIT 1000000                        /* maximum value for n */intmain(int argc, char **argv) {        int *A;                              /* the array of freqs */        int *B;                              /* a copy of A */        int n;                               /* number of symbols */        int totfreq;                         /* total frequency */        int bits;                            /* total bits in codewords */        double ent;                          /* entropy */        int i;        /* claim space for arrays */        scanf("%d", &n);        if (n <= 0 || n > LIMIT) {                fprintf(stderr, "%s: n should be at least 0 and less than %d\n",                        argv[0], LIMIT);                exit(1);        }        if ((A = (int *)malloc(n*sizeof(int))) == (int *)NULL            || (B = (int *)malloc(n*sizeof(int))) == (int *)NULL) {                    fprintf(stderr, "%s: unable to allocate memory\n",                        argv[0]);                exit(1);        }        /* read symbol frequencies */        for (i=0; i<n; i++) {                if (scanf("%d", A+i) == EOF) {                        n = i;                        break;                }        }        /* calculate entropy, and check for sensible input values */        totfreq = 0;        for (i=0; i<n; i++) {                totfreq += A[i];                if (A[i] < 0 || (i>0 && A[i-1] > A[i])) {                        fprintf(stderr, "%s: %s %s\n",                                argv[0],                                "input frequencies must be non-negative",                                "and non-decreasing");                        exit(1);                }        }        if (totfreq <= 0) {                fprintf(stderr, "%s: sum of frequencies must be positive\n",                        argv[0]);                exit(1);        }        ent = 0.0;        for (i=0; i<n; i++) {                double prob = (double)A[i]/totfreq;                ent += - prob * log2(prob);        }        /* make a copy of A into B so that average weighted codeword           length can be calculated once the codeword lengths are known;           note that B is _not_ used by the length calculation process */        for (i=0; i<n; i++) {                B[i] = A[i];        }        /* now calculate the minimum-redundancy codeword lengths */        calculate_minimum_redundancy(A, n);        /* and evaluate average codeword length */        bits = 0;        for (i=0; i<n; i++) {                bits += A[i] * B[i];        }        /*  and print the results */	if (n <= 100) {		for (i=0; i<n; i++) {			printf("f_%02d = %4d, |c_%02d| = %2d\n",				i, B[i], i, A[i]);		}	}        printf("entropy                 = %5.2f bits per symbol\n", ent);        printf("minimum-redundancy code = %5.2f bits per symbol\n",                 (double)bits/totfreq);	if (ent > 0.0)		printf("inefficiency            = %5.2f%%\n", 			100*(double)bits/totfreq/ent - 100.0);        	free(A);	free(B);	return(0);}/*** Function to calculate in-place a minimum-redundancy code     Parameters:        A        array of n symbol frequencies, non-decreasing        n        number of symbols in A*/voidcalculate_minimum_redundancy(int A[], int n) {        int root;                  /* next root node to be used */        int leaf;                  /* next leaf to be used */        int next;                  /* next value to be assigned */        int avbl;                  /* number of available nodes */        int used;                  /* number of internal nodes */        int dpth;                  /* current depth of leaves */        /* check for pathological cases */        if (n==0) { return; }        if (n==1) { A[0] = 0; return; }        /* first pass, left to right, setting parent pointers */        A[0] += A[1]; root = 0; leaf = 2;        for (next=1; next < n-1; next++) {                /* select first item for a pairing */                if (leaf>=n || A[root]<A[leaf]) {                        A[next] = A[root]; A[root++] = next;                } else                        A[next] = A[leaf++];                /* add on the second item */                if (leaf>=n || (root<next && A[root]<A[leaf])) {                        A[next] += A[root]; A[root++] = next;                } else                        A[next] += A[leaf++];        }                /* second pass, right to left, setting internal depths */        A[n-2] = 0;        for (next=n-3; next>=0; next--)                A[next] = A[A[next]]+1;        /* third pass, right to left, setting leaf depths */        avbl = 1; used = dpth = 0; root = n-2; next = n-1;        while (avbl>0) {                while (root>=0 && A[root]==dpth) {                        used++; root--;                }                while (avbl>used) {                        A[next--] = dpth; avbl--;                }                avbl = 2*used; dpth++; used = 0;        }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -