哈夫曼樹創建和哈夫曼碼生成

直接上代碼。
HTree.h

typedef struct HTreeNode {
    char data;
    int weight;
    int parent, lchild, rchild;
}HTreeNode;

main.cpp

#include<stdio.h>
#include<stdlib.h>
#include<string>
#include"HTree.h"

HTreeNode* InitHTree(int num);          //初始化哈夫曼樹結點
void GetMin(HTreeNode* array, int start, int end, int &s1, int &s2);    //取兩個權重最新的結點
void CreateHTree(HTreeNode* array, int num);                            //創建哈弗曼樹
void CreateHuffmanCode(HTreeNode* array, int numOfLeaf, char** code);   //創建哈弗曼碼

int main() {
    int numOfLeaf;
    scanf_s("%d\n", &numOfLeaf);

    HTreeNode* array;                   //哈弗曼樹指針
    array = InitHTree(2 * numOfLeaf);
    CreateHTree(array, numOfLeaf);
    int i;
    for (i = 1; i <= 2 * numOfLeaf - 1; i++) {
        printf("%c ", array[i].data);
        printf("%d ", array[i].weight);
    }

    char** huffmanCode;             //哈弗曼碼指針
    huffmanCode = (char**)malloc(sizeof(char*) * (numOfLeaf + 1));
    CreateHuffmanCode(array, numOfLeaf, huffmanCode);

    printf("\n");
    for (i = 1; i <= numOfLeaf; i++) {
        printf("%c: ", array[i].data);
        printf("%s\n", huffmanCode[i]);
    }

    return 0;
}

HTreeNode* InitHTree(int num) {
    HTreeNode* array;
    array = (HTreeNode*)malloc(sizeof(HTreeNode) * num);
    for (int i = 1; i < num; i++) {
        array[i].data = array[i].lchild = array[i].parent = array[i].rchild = array[i].weight = 0;
    }
    return array;
}

void CreateHTree(HTreeNode* array, int numOfLeaf) {
    for (int i = 1; i <= numOfLeaf; i++) {
        char c;
        c = getchar();
        array[i].data = c;      //賦值結點數據值
        c = getchar();
        array[i].weight = int(c - '0'); //賦值結點權重值
    }
    /*建樹*/
    int num = numOfLeaf;
    while (num < 2 * numOfLeaf - 1) {
        int s1, s2;
        GetMin(array, 1, num, s1, s2);      //找權重最小的兩個結點
        array[num + 1].lchild = s1;
        array[num + 1].rchild = s2;
        array[num + 1].weight = array[s1].weight + array[s2].weight;
        num++;
        array[s1].parent = num;
        array[s2].parent = num;

    }
}

void GetMin(HTreeNode* array, int start, int end, int &s1, int &s2) {   //s1記錄最小值的下標,s2記錄第二小值的下標
    int min1 = 9999;
    int min2 = min1;
    for (int i = start; i <= end; i++) {
        if (array[i].parent != 0)
            continue;
        if (array[i].weight < min1) {
            min2 = min1;
            min1 = array[i].weight;
            s2 = s1;
            s1 = i;
        }
        else {
            if (array[i].weight < min2) {
                min2 = array[i].weight;
                s2 = i;
            }
        }
    }
}

void CreateHuffmanCode(HTreeNode* array, int numOfLeaf, char** code) {
    char *temp;
    temp = (char*)malloc(sizeof(char) * numOfLeaf);
    temp[numOfLeaf - 1] = '\0';
    int start;
    int c, f;
    for (int i = 1; i <= numOfLeaf; i++) {
        start = numOfLeaf - 1;
        c = i; f = array[i].parent;
        while (f != 0) {
            --start;
            if (array[f].lchild == c)   //左側爲0
                temp[start] = '0';
            else
                temp[start] = '1';      //右側爲1
            c = f;
            f = array[c].parent;
        }
        code[i] = (char*)malloc(sizeof(char) * (numOfLeaf - start));
        strcpy_s(code[i], numOfLeaf - start, &temp[start]);     //注意strcpy和strcpy_s的區別
    }
    free(temp);
}

這裏寫圖片描述

發佈了76 篇原創文章 · 獲贊 83 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章