1. 程式人生 > 實用技巧 >HashMap的初始化,到底都做了什麼?

HashMap的初始化,到底都做了什麼?

1、哈夫曼樹
在介紹哈夫曼樹之前需要給出幾個概念。
(1)路徑和路徑長度路徑是指從根結點的分支序列,路徑長度是指根節點到該節點所經過的分支數目。
(2)節點的權和帶權路徑長度:在實際應用中,人們常常給樹的每個給點賦予一個具有某種實際意義的實數,稱該實數為這個節點的。在樹結構中,把從樹某一根部到該節點的路徑長度與該節點的權的乘積,稱為該節點的帶權路徑長度
(3)樹帶權的路徑長度:樹的帶權路徑長度為樹中從根到所有葉子節點的各個帶權路徑長度之和。

舉例:計算帶權路徑長度

給定n個實數w1,…w2,求一個具有n個終端結點的二叉樹,使其帶權路徑長度最小。將給定節點構成一顆樹帶權樹路徑長度最小的二叉樹

最短的二叉樹,被稱為哈夫曼樹

2、構建哈夫曼樹
構造哈夫曼樹的演算法步驟如下:
第一步,初始化:用給定的n個權值{w1,w2,…,wn}構造n顆二叉樹並構成的森林F={T1,……,Tn},其中每一個二叉樹Ti都只有一個權值為wi(一個T中只有一個w1或w2……)的根節點,其左、右子樹為空。
第二步,找最小樹:在森林F中選擇兩顆根節點權值最小的二叉樹,作為一顆新的二叉樹的左、右子樹,標記新二叉樹的根節點權值為其左、右子樹的根節點權值之和。
第三步,刪除與加入:從F中刪除被選中的那兩棵二叉樹,同時把新構成的二叉樹加入到森林F中
第四步,判斷:重複第二步、第三步操作,直到森林中只包含有一棵二叉樹為止,此時得到的二叉樹就是哈夫曼樹。
哈夫曼樹構建演算法實現:

(使用軟體VS)

typedef struct {

int weight;         // 結點權值?

int parent, lc, rc; // 雙親結點和左 右子節點

} HTNode, *HuffmanTree;

void Select(HuffmanTree &HT, int n, int &s1, int &s2)

{

int minum;      // 定義一個臨時變數儲存最小值?

for(int i=1; i<=n; i++)     // 以下是找到第一個最小值

{

    if(HT[i].parent == 0)

    {

        minum = i;

        break;

    }

}

for(int i=1; i<=n; i++)

{

    if(HT[i].parent == 0)

        if(HT[i].weight < HT[minum].weight)

            minum = i;

}

s1 = minum;

// 以下是找到第二個最小值,且與第一個不同

for(int i=1; i<=n; i++)     

{

    if(HT[i].parent == 0 && i != s1)

    {

        minum = i;

        break;

    }

}

for(int i=1; i<=n; i++)

{

    if(HT[i].parent == 0 && i != s1)

        if(HT[i].weight < HT[minum].weight)

            minum = i;

}

s2 = minum;

}

void CreatHuff(HuffmanTree &HT, int *w, int n)

{

int m, s1, s2;

m = n * 2 - 1;  // 總結點的個數

HT = new HTNode[m + 1]; // 分配空間

for(int i=1; i<=n; i++) // 1 - n 存放葉子結點,初始化

{

    HT[i].weight = w[i];

    HT[i].parent = 0;

    HT[i].lc = 0;

    HT[i].rc = 0;

}

for(int i=n+1; i<=m; i++)   // 非葉子結點的初始化

{

    HT[i].weight = 0;

    HT[i].parent = 0;

    HT[i].lc = 0;

    HT[i].rc = 0;

}



printf("\nthe HuffmanTree is: \n");



for(int i = n+1; i<=m; i++)     // 建立非葉子節點,建哈夫曼樹

{   // 在HT[1]~HT[i-1]的範圍內選擇兩個parent為0且weight最小的兩個結點,其序號分別賦值給 s1 s2

    Select(HT, i-1, s1, s2);

    HT[s1].parent = i;  // 刪除這兩個結點

    HT[s2].parent = i;

    HT[i].lc = s1;      // 生成新的樹,左右子節點是 s1和s2

    HT[i].rc = s2;

    HT[i].weight = HT[s1].weight + HT[s2].weight;   // 新樹的權??

    printf("%d (%d, %d)\n", HT[i].weight, HT[s1].weight, HT[s2].weight);

}

printf("\n");

}

int main()

{

HuffmanTree HT;



int *w, n, wei;

printf("input the number of node\n");

scanf("%d", &n);

w = new int[n+1];

printf("\ninput the %dth node of value\n", n);



for(int i=1; i<=n; i++)

{

    scanf("%d", &wei);

    w[i] = wei;

}

CreatHuff(HT, w, n);







return 0;

}