zoukankan      html  css  js  c++  java
  • 【C++编程赛】(1)哈夫曼树

    #include<iostream>
    using namespace std;
    int m = 0;
    typedef struct {
    	int weight;
    	int jilu;//记录编码的权值
    	int parent, lchild, rchild;
    }HTNode, *HuffmanTree; //动态分配数组存储哈夫曼树
    typedef char *HuffmanCode; //动态分配数组存储哈夫曼编码表
    
    void Select(HuffmanTree HT, int n,int &s1,int &s2) {
    	int i, j;
    	for (i = 1; i <= n; i++)
    	if (!HT[i].parent){ s1 = i; break; }
    	for (j = i + 1; j <= n; j++)
    	if (!HT[j].parent){ s2 = j; break; }
    	for (i = 1; i <= n; i++)
    	if ((HT[s1].weight>HT[i].weight) && (!HT[i].parent) && (s2 != i))s1 = i;
    	for (j = 1; j <= n; j++)
    	if ((HT[s2].weight>HT[j].weight) && (!HT[j].parent) && (s1 != j))s2 = j;
    }
    
    void HuffmanCoding(HuffmanTree &HT, HuffmanCode HC[],int n) {
    	// w存放n个字符的权值(均>0),构造哈夫曼树HT,
    	// 并求出n个字符的哈夫曼编码HC
    	int i, j,s1,s2;
    	char *cd;
    	int p;
    	int cdlen;
    	if (n <= 1) return;
    	m = 2 * n - 1;
    	HT = (HuffmanTree)malloc((m + 1) * sizeof(HTNode)); // 0号单元未用
    	for (i =1; i <= m; i++) { //初始化
    		HT[i].parent = 0;HT[i].lchild = 0;HT[i].rchild = 0;
    	}
    	for (i = 1; i <= n; i++) { //输入权值
    		cin>>HT[i].weight;
    		HT[i].jilu = HT[i].weight;
    	}
    	for (i = n + 1; i <= m; i++) { // 建哈夫曼树
    		// 在HT[1..i-1]中选择parent为0且weight最小的两个结点,
    		// 其序号分别为s1和s2。
    		Select(HT, i - 1,s1,s2);
    		HT[s1].parent = i; HT[s2].parent = i;
    		if (HT[s1].weight<=HT[s2].weight)
    		{
    			HT[i].lchild = s1; HT[i].rchild = s2;
    		}
    		else{HT[i].lchild = s2; HT[i].rchild = s1;}
    		HT[i].weight = HT[s1].weight + HT[s2].weight;
    	}
    	printf(" 下标  权值  父亲  左孩子  右孩子");
    	for (j = 1; j <= i-1; j++)
    	{
    		printf("
    [%2d]%6d%6d%6d%6d", j, HT[j].weight, HT[j].parent, HT[j].lchild, HT[j].rchild);
    	}
    
    	//------无栈非递归遍历哈夫曼树,求哈夫曼编码
    	cd = (char *)malloc(n*sizeof(char)); // 分配求编码的工作空间
    	p = m; cdlen = 0;
    	for (i = 1; i <= m; ++i) // 遍历哈夫曼树时用作结点状态标志
    		HT[i].weight = 0;
    	while (p) {
    		if (HT[p].weight == 0) { // 向左
    			HT[p].weight = 1;
    			if (HT[p].lchild != 0) { p = HT[p].lchild; cd[cdlen++] = '0'; }
    			else if (HT[p].rchild == 0) { // 登记叶子结点的字符的编码
    				HC[p] = (char *)malloc((cdlen + 1) * sizeof(char));
    				cd[cdlen] = ''; strcpy(HC[p], cd); // 复制编码(串)
    			}
    		}
    		else if (HT[p].weight == 1) { // 向右
    			HT[p].weight = 2;
    			if (HT[p].rchild != 0) { p = HT[p].rchild; cd[cdlen++] = '1'; }
    		}
    		else { // HT[p].weight==2,退回退到父结点,编码长度减1
    			HT[p].weight = 0; p = HT[p].parent; --cdlen;
    		}
    	}
    } // HuffmanCoding
    void main() {
    	HuffmanTree HT;
    	HuffmanCode *HC;
    	int n, i;
    	cout << "请输入叶子结点个数:" << endl;
    	cin >> n;
    	HC = (HuffmanCode *)malloc(n*sizeof(HuffmanCode));
    	cout << "请输入叶子结点的权值:" << endl;
    	HuffmanCoding(HT, HC,n);
    	for (i = 1; i <= n; i++)
    	{
    		printf("
    %2d编码为:%s", HT[i].jilu, HC[i]);
    	}
    	getchar();
    }
    
  • 相关阅读:
    WCF配置文件注释
    WCF 契约
    等待窗口 or splash 窗体用法
    SOA架构概述
    在高负载网站性能优化
    WCF应用实例
    SOA快速指南 1 2 3,第 3 部分: 服务实现及架构设计
    WCF Binding
    已经添加了对EXCEL的引用,但在出现Microsoft.Office.Interop.Excel.Application没有定义
    Oracle 11g 转换内部编码
  • 原文地址:https://www.cnblogs.com/tzeyeung/p/13531375.html
Copyright © 2011-2022 走看看