数据结构学习笔记04树(堆 哈夫曼树 并查集)

一.堆(heap)

优先队列(Priority Queue):特殊的“队列”,取出元素的顺序是依照元素的优先权(关键字)大小,而不是元素进入队列的先后顺序。

数组 :
插入 — 元素总是插入尾部 ~ O ( 1 )
删除 — 查找最大(或最小)关键字 ~ O ( n )
从数组中删去需要移动元素 ~ O( n )
链表:
插入 — 元素总是插入链表的头部 ~ O ( 1 )
删除 — 查找最大(或最小)关键字 ~ O ( n )
删去结点 ~ O( 1 )
有序数组:
插入 — 找到合适的位置 ~ O( n ) 或 O(log2 n )
移动元素并插入 ~ O( n )
删除 — 删去最后一个元素 ~ O( 1 )
有序链表:
插入 — 找到合适的位置 ~ O( n )
插入元素 ~ O( 1 )
删除 — 删除首元素或最后元素 ~ O( 1 )
二叉树
    删除会导致不平衡

若采用数组或链表实现优先队列

优先队列的完全二叉树表示

的两个特性

  结构性:用数组表示的完全二叉树;

  有序性:任一结点的关键字是其子树所有结点的最大值(或最小值)

    “最大堆(MaxHeap)”,也称“大顶堆”:最大值

     “最小堆(MinHeap)”,也称“小顶堆” :最小值

1.最大堆(代码:sj4_3)

  1 //最大堆
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4
  5 #define MAXDATA 1000  /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */
  6 #define ERROR -1 /* 错误标识应根据具体情况定义为堆中不可能出现的元素值 */
  7
  8 typedef int ElementType;
  9
 10 typedef struct HNode *Heap; /* 堆的类型定义 */
 11 struct HNode {
 12     ElementType *Data; /* 存储元素的数组 */
 13     int Size;          /* 堆中当前元素个数 */
 14     int Capacity;      /* 堆的最大容量 */
 15 };
 16 typedef Heap MaxHeap; /* 最大堆 */
 17
 18 MaxHeap CreateHeap( int MaxSize );
 19 bool IsFull( MaxHeap H );
 20 bool Insert( MaxHeap H, ElementType X );
 21 bool IsEmpty( MaxHeap H );
 22 ElementType DeleteMax( MaxHeap H );
 23 void PercDown( MaxHeap H, int p );
 24 void BuildHeap( MaxHeap H );
 25
 26 int main()
 27 {
 28     MaxHeap Heap;
 29     Heap = CreateHeap( 10 );
 30     BuildHeap(Heap);
 31     Insert( Heap, 1);
 32     Insert( Heap, 2);
 33     Insert( Heap, 3);
 34     ElementType Max = DeleteMax( Heap );
 35     printf("%d\n",Max);
 36     return 0;
 37 }
 38
 39 /* 创建容量为MaxSize的空的最大堆 */
 40 MaxHeap CreateHeap( int MaxSize )
 41 {
 42
 43     MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
 44     H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
 45     H->Size = 0;
 46     H->Capacity = MaxSize;
 47     H->Data[0] = MAXDATA; /* 定义"哨兵"为大于堆中所有可能元素的值*/
 48
 49     return H;
 50 }
 51
 52 bool IsFull( MaxHeap H )
 53 {
 54     return (H->Size == H->Capacity);
 55 }
 56
 57 /* 将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵 */
 58 bool Insert( MaxHeap H, ElementType X )
 59 {
 60     if ( IsFull(H) ) {
 61         printf("最大堆已满");
 62         return false;
 63     }
 64     int i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
 65     for ( ; H->Data[i/2] < X; i /= 2 )
 66         H->Data[i] = H->Data[i/2]; /* 上滤X */
 67     H->Data[i] = X; /* 将X插入 */
 68     return true;
 69 }
 70
 71 bool IsEmpty( MaxHeap H )
 72 {
 73     return (H->Size == 0);
 74 }
 75
 76 /* 从最大堆H中取出键值为最大的元素,并删除一个结点 */
 77 ElementType DeleteMax( MaxHeap H )
 78 {
 79     int Parent, Child;
 80     ElementType MaxItem, X;
 81
 82     if ( IsEmpty(H) ) {
 83         printf("最大堆已为空");
 84         return ERROR;
 85     }
 86
 87     MaxItem = H->Data[1]; /* 取出根结点存放的最大值 */
 88     /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
 89     X = H->Data[H->Size--]; /* 注意当前堆的规模要减小 */
 90     for( Parent = 1; Parent * 2 <= H->Size; Parent = Child ) {
 91         Child = Parent * 2;
 92         if( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
 93             Child++;  /* Child指向左右子结点的较大者 */
 94         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
 95         else  /* 下滤X */
 96             H->Data[Parent] = H->Data[Child];
 97     }
 98     H->Data[Parent] = X;
 99
100     return MaxItem;
101 }
102
103 /*----------- 建造最大堆 -----------*/
104 /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
105 void PercDown( MaxHeap H, int p )
106 {
107     int Parent, Child;
108     ElementType X;
109
110     X = H->Data[p]; /* 取出根结点存放的值 */
111     for( Parent = p; Parent*2 <= H->Size; Parent = Child ) {
112         Child = Parent * 2;
113         if( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
114             Child++;  /* Child指向左右子结点的较大者 */
115         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
116         else  /* 下滤X */
117             H->Data[Parent] = H->Data[Child];
118     }
119     H->Data[Parent] = X;
120 }
121
122 /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
123 /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
124 void BuildHeap( MaxHeap H )
125 {
126     /* 从最后一个结点的父节点开始,到根结点1 */
127     for(int i = H->Size/2; i > 0; i-- )
128         PercDown( H, i );
129 }

sj4_3

typedef struct HNode *Heap; /* 堆的类型定义 */
struct HNode {
  ElementType *Data; /* 存储元素的数组 */
  int Size; /* 堆中当前元素个数 */
  int Capacity; /* 堆的最大容量 */
};
typedef Heap MaxHeap; /* 最大堆 */

1.创建最大堆

/* 创建容量为MaxSize的空的最大堆 */
MaxHeap CreateHeap( int MaxSize )
{ 

    MaxHeap H = (MaxHeap)malloc(sizeof(struct HNode));
    H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
    H->Size = 0;
    H->Capacity = MaxSize;
    H->Data[0] = MAXDATA; /* 定义"哨兵"为大于堆中所有可能元素的值*/

    return H;
}
 

2.最大堆的插入

将新插入的元素放在数组的最后位置。

  case1:新插入元素小于其parent。例如插入20,未破坏其有序性,插入成功。

  case2:新插入元素大于其parent。例如插入35,破坏其结点是其子树所有结点的最大值,交换35与其parent31位置。

  case3:新插入元素大于其parent的parent……。例如插入58,若其大于parent,交换,一直往上换。

 1 /* 将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵 */
 2 bool Insert( MaxHeap H, ElementType X )
 3 {
 4     if ( IsFull(H) ) {
 5         printf("最大堆已满");
 6         return false;
 7     }
 8     int i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
 9     for ( ; H->Data[i/2] < X; i /= 2 )
10         H->Data[i] = H->Data[i/2]; /* 上滤X */
11     H->Data[i] = X; /* 将X插入 */
12     return true;
13 }

3.最大堆的删除

获取根(即最大值),删除最后的结点,放入根位置。取根最大的孩子与根交换,最大孩子的最大孩子与其交换,一直向下换。

 1 /* 从最大堆H中取出键值为最大的元素,并删除一个结点 */
 2 ElementType DeleteMax( MaxHeap H )
 3 {
 4     int Parent, Child;
 5     ElementType MaxItem, X;
 6
 7     if ( IsEmpty(H) ) {
 8         printf("最大堆已为空");
 9         return ERROR;
10     }
11
12     MaxItem = H->Data[1]; /* 取出根结点存放的最大值 */
13     /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */
14     X = H->Data[H->Size--]; /* 注意当前堆的规模要减小 */
15     for( Parent = 1; Parent * 2 <= H->Size; Parent = Child ) {
16         Child = Parent * 2;
17         if( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
18             Child++;  /* Child指向左右子结点的较大者 */
19         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
20         else  /* 下滤X */
21             H->Data[Parent] = H->Data[Child];
22     }
23     H->Data[Parent] = X;
24
25     return MaxItem;
26 } 

4.最大堆的建立:将已经存在的N个元素按最大堆的要求存放在一个一维数组中

  方法1:通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中去,其时间代价最大为O(N logN)。    

  方法2:在线性时间复杂度下建立最大堆。
    ①将N个元素按输入顺序存入,先满足完全二叉树的结构特性
    ②调整各结点位置,以满足最大堆的有序特性。

从最小单位堆开始建堆,从后往前,第一个有孩子的最小单位堆开始。

 1 /*----------- 建造最大堆 -----------*/
 2 /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */
 3 void PercDown( MaxHeap H, int p )
 4 {
 5     int Parent, Child;
 6     ElementType X;
 7
 8     X = H->Data[p]; /* 取出根结点存放的值 */
 9     for( Parent = p; Parent*2 <= H->Size; Parent = Child ) {
10         Child = Parent * 2;
11         if( (Child != H->Size) && (H->Data[Child] < H->Data[Child+1]) )
12             Child++;  /* Child指向左右子结点的较大者 */
13         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
14         else  /* 下滤X */
15             H->Data[Parent] = H->Data[Child];
16     }
17     H->Data[Parent] = X;
18 }
19
20 /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
21 /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
22 void BuildHeap( MaxHeap H )
23 {
24     /* 从最后一个结点的父节点开始,到根结点1 */
25     for(int i = H->Size/2; i > 0; i-- )
26         PercDown( H, i );
27 }

2.最小堆(代码:sj4_4)

同理

  1 //最小堆
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4
  5 #define MINDATA -1000  /* 该值应根据具体情况定义为小于堆中所有可能元素的值 */
  6 #define ERROR -1 /* 错误标识应根据具体情况定义为堆中不可能出现的元素值 */
  7
  8 typedef int ElementType;
  9
 10 typedef struct HNode *Heap; /* 堆的类型定义 */
 11 struct HNode {
 12     ElementType *Data; /* 存储元素的数组 */
 13     int Size;          /* 堆中当前元素个数 */
 14     int Capacity;      /* 堆的最大容量 */
 15 };
 16 typedef Heap MinHeap; /* 最小堆 */
 17
 18 MinHeap CreateHeap( int MaxSize );
 19 bool IsFull( MinHeap H );
 20 bool Insert( MinHeap H, ElementType X );
 21 bool IsEmpty( MinHeap H );
 22 ElementType DeleteMin( MinHeap H );
 23 void PercDown( MinHeap H, int p );
 24 void BuildHeap( MinHeap H );
 25
 26 int main()
 27 {
 28     MinHeap Heap;
 29     Heap = CreateHeap( 10 );
 30     BuildHeap(Heap);
 31     Insert( Heap, 1);
 32     Insert( Heap, 2);
 33     Insert( Heap, 3);
 34     ElementType Min = DeleteMin( Heap );
 35     printf("%d\n",Min);
 36     return 0;
 37 }
 38
 39 /* 创建容量为MaxSize的空的最小堆 */
 40 MinHeap CreateHeap( int MaxSize )
 41 {
 42
 43     MinHeap H = (MinHeap)malloc(sizeof(struct HNode));
 44     H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
 45     H->Size = 0;
 46     H->Capacity = MaxSize;
 47     H->Data[0] = MINDATA; /* 定义"哨兵"为小于堆中所有可能元素的值*/
 48
 49     return H;
 50 }
 51
 52 bool IsFull( MinHeap H )
 53 {
 54     return (H->Size == H->Capacity);
 55 }
 56
 57 /* 将元素X插入最小堆H,其中H->Data[0]已经定义为哨兵 */
 58 bool Insert( MinHeap H, ElementType X )
 59 {
 60     if ( IsFull(H) ) {
 61         printf("最小堆已满");
 62         return false;
 63     }
 64     int i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
 65     for ( ; H->Data[i/2] > X; i /= 2 )
 66         H->Data[i] = H->Data[i/2]; /* 上滤X */
 67     H->Data[i] = X; /* 将X插入 */
 68     return true;
 69 }
 70
 71 bool IsEmpty( MinHeap H )
 72 {
 73     return (H->Size == 0);
 74 }
 75
 76 /* 从最小堆H中取出键值为最小的元素,并删除一个结点 */
 77 ElementType DeleteMin( MinHeap H )
 78 {
 79     int Parent, Child;
 80     ElementType MinItem, X;
 81
 82     if ( IsEmpty(H) ) {
 83         printf("最小堆已为空");
 84         return ERROR;
 85     }
 86
 87     MinItem = H->Data[1]; /* 取出根结点存放的最小值 */
 88     /* 用最小堆中最后一个元素从根结点开始向上过滤下层结点 */
 89     X = H->Data[H->Size--]; /* 注意当前堆的规模要减小 */
 90     for( Parent = 1; Parent * 2 <= H->Size; Parent = Child ) {
 91         Child = Parent * 2;
 92         if( (Child != H->Size) && (H->Data[Child] > H->Data[Child+1]) )
 93             Child++;  /* Child指向左右子结点的较小者 */
 94         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
 95         else  /* 下滤X */
 96             H->Data[Parent] = H->Data[Child];
 97     }
 98     H->Data[Parent] = X;
 99
100     return MinItem;
101 }
102
103 /*----------- 建造最小堆 -----------*/
104 /* 下滤:将H中以H->Data[p]为根的子堆调整为最小堆 */
105 void PercDown( MinHeap H, int p )
106 {
107     int Parent, Child;
108     ElementType X;
109
110     X = H->Data[p]; /* 取出根结点存放的值 */
111     for( Parent = p; Parent*2 <= H->Size; Parent = Child ) {
112         Child = Parent * 2;
113         if( (Child != H->Size) && (H->Data[Child] > H->Data[Child+1]) )
114             Child++;  /* Child指向左右子结点的较小者 */
115         if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
116         else  /* 下滤X */
117             H->Data[Parent] = H->Data[Child];
118     }
119     H->Data[Parent] = X;
120 }
121
122 /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
123 /* 这里假设所有H->Size个元素已经存在H->Data[]中 */
124 void BuildHeap( MinHeap H )
125 {
126     /* 从最后一个结点的父节点开始,到根结点1 */
127     for(int i = H->Size/2; i > 0; i-- )
128         PercDown( H, i );
129 }

sj4_4

二.哈夫曼树与哈弗曼编码

1.哈夫曼树

带权路径长度(WPL):设二叉树有n个叶子结点,每个叶子结点带有权值 Wk,从根结点到每个叶子结点的长度为 Lk,则每个叶子结点的带权路径长度之和就是:

      WPL =  

最优二叉树或哈夫曼树: WPL最小的二叉树

 

哈夫曼树的特点:
  ①没有度为1的结点

  ②n个叶子结点的哈夫曼树共有2n-1个结点

  ③哈夫曼树的任意非叶节点的左右子树交换后仍是哈夫曼树

  ④对同一组权值{w1 ,w2 , …… , wn},存在不同构的两棵哈夫曼树

1.哈夫曼树的构造

每次把权值最小的两颗二叉树合并.(利用堆)

->-->--->---->

 1 //Huffman Tree
 2 typedef struct TreeNode *HuffmanTree;
 3 struct TreeNode{
 4     int weight;
 5     HuffmanTree left,right;
 6 };
 7
 8 HuffmanTree Huffman(MinHeap H)
 9 {/*假设H->Size个权值已经存在在H->data[]->weight里*/
10     HuffmanTree T;
11     BuildMinHeap(H);//将H->data[]按权值调整为最小堆
12     for(int i = 1; i < H->Size; i++) {//做H->Size-1次合并
13         T = (HuffmanTree)malloc(sizeof(struct TreeNode));//建立新结点
14         T->left = DeleteMin(H);    //从最小堆中删除一个结点,作为新T的左子结点
15         T->right = DeleteMin(H);//从最小堆中删除一个结点,作为新T的右子结点
16         T->weight = T->left->weight + T->right->weight;//计算新权值
17         Insert(H,T);//将新T插入最小堆
18     }
19     T = DeleteMin(H);
20     return T;
21 }

2.哈弗曼编码

前缀码(prefix code):任何字符的编码都不是另一字符编码的前缀
  可以无二义地解码

构造一颗编码代价最小的二叉树:HaffumanTree

三.并查集

集合的表示
  集合运算:交、并、补、差,判定一个元素是否属于某一集合
  并查集:集合并、查某元素属于什么集合
  并查集问题中集合存储如何实现:

①可以用树结构表示集合,树的每个结点代表一个集合元素

②采用数组存储形式

合并后根为负数,负数代表根,其绝对值代表个数。

1.查找某个元素所在的集合(用根结点表示)

1 SetName Find( ElementType S[], ElementType X )
2 { /* 默认集合元素全部初始化为-1 */
3     if ( S[X] < 0 ) /* 找到集合的根 */
4         return X;
5     else
6         return S[X] = Find( S, S[X] ); /* 路径压缩 */
7 }

2.集合的并运算

  ①分别找到X1和X2两个元素所在集合树的根结点
  ②如果它们不同根,则将其中一个根结点的父结点指针设置成另一个根结点的数组下标。

为了改善合并以后的查找性能,采用小的集合合并到相对大的集合中。

 1 /* 这里默认Root1和Root2是不同集合的根结点 */
 2 void Union( ElementType S[], SetName Root1, SetName Root2 )
 3 {
 4     /* 保证小集合并入大集合 */
 5     if ( S[Root2] < S[Root1] ) { /* 如果集合2比较大 */
 6         S[Root2] += S[Root1];     /* 集合1并入集合2  */
 7         S[Root1] = Root2;
 8     }
 9     else {                         /* 如果集合1比较大 */
10         S[Root1] += S[Root2];     /* 集合2并入集合1  */
11         S[Root2] = Root1;
12     }
13 }

时间: 2024-08-13 04:13:38

数据结构学习笔记04树(堆 哈夫曼树 并查集)的相关文章

《大话数据结构》笔记(6-3)--树:赫夫曼树

代码实现: 第六章    树:赫夫曼树 赫夫曼树定义与原理 从树中一个结点到另一个结点之间的分支构成两个结点之间的路径,路径上的分支数目称作路径长度. 树的路径长度就是从树根到每一结点的路径长度之和. 对于带权的结点,结点的带权路径长度为从该结点到树根之间的路径长度与结点上权的乘积. 树的带权路径长度为树中所有叶子结点的带权路径长度之和. 假设有n个权值{w1, w2, ..., wn},构造一棵有n个叶子结点的二叉树,每个叶子结点带权wk ,每个叶子的路径长度为lk,则其中带权路径长度WPL最

Huffman tree(赫夫曼树、霍夫曼树、哈夫曼树、最优二叉树)

flyfish 2015-8-1 Huffman tree因为翻译不同所以有其他的名字 赫夫曼树.霍夫曼树.哈夫曼树 定义引用自严蔚敏<数据结构> 路径 从树中一个结点到另一个结点之间的分支构成两个结点之间的路径. 路径长度 路径上的分支数目称作路径长度. 树的路径长度 树的路径长度就是从根节点到每一结点的路径长度之和. 结点的带权路径长度 结点的带权路径长度就是从该结点到根节点之间的路径长度与结点上权的乘积. 树的带权路径长度 树的带权路径长度就是树中所有叶子结点的带权路径长度之和,通常记做

数据结构学习笔记04树(二叉树、二叉搜索树、平衡二叉树)

一.树 树的基本术语 ①结点的度(Degree):结点的子树个数 ②树的度:树的所有结点中最大的度数 ③叶结点(Leaf):度为0的结点 ④父结点(Parent):有子树的结点是其子树的根结点的父结点 ⑤子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点:子结点也称孩子结点. ⑥兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点. ⑦路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2 ,… , nk , ni是 ni+1的父结点.路径所包含边

数据结构(三):非线性逻辑结构-特殊的二叉树结构:堆、哈夫曼树、二叉搜索树、平衡二叉搜索树、红黑树、线索二叉树

在上一篇数据结构的博文<数据结构(三):非线性逻辑结构-二叉树>中已经对二叉树的概念.遍历等基本的概念和操作进行了介绍.本篇博文主要介绍几个特殊的二叉树,堆.哈夫曼树.二叉搜索树.平衡二叉搜索树.红黑树.线索二叉树,它们在解决实际问题中有着非常重要的应用.本文主要从概念和一些基本操作上进行分类和总结. 一.概念总揽 (1) 堆 堆(heap order)是一种特殊的表,如果将它看做是一颗完全二叉树的层次序列,那么它具有如下的性质:每个节点的值都不大于其孩子的值,或每个节点的值都不小于其孩子的值

数据结构——哈夫曼树

转自:http://www.cnblogs.com/skywang12345/p/3706833.html 哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树. 这个定义里面涉及到了几个陌生的概念,下面就是一颗哈夫曼树,我们来看图解答. (01) 路径和路径长度 定义:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径.通路中分支的数目称

数据结构之哈夫曼树

#include <iostream> #include <iomanip> #include <string> using namespace std; typedef struct { string name; int weight; int parent, lchild, rchild; int visited; //设置visited选项来表示每次查找最小权值后的删除,0代表未删除,1表示删除 }HTNode,*HuffmanTree; int Min(Huff

哈夫曼树学习

基本概念: 1.路径是指从一个节点到另一个节点之间的分支序列,路径长度是指从一个节点到另一个节点所经过的分支数目. 2.实际生活中,我们为每一个节点赋予实际的意义的实数,称该实数为节点的权.在树形结构中把树根到某一节点的路径长度与该节点的权乘积叫该节点的带权路径长度. 3.树的带权路径长度是树中所有叶子节点的带权路径长度之和.                                  举例说明一下:c的权重分别为7,5,2,4.路径长度为层数-1即到根节点的长度 哈夫曼树: 哈夫曼树又叫

5678: 数据结构实验:哈夫曼树和编码

描述 当用 n 个结点(都做叶子结点且都有各自的权值)试图构建一棵树时,如果构建的这棵树的带权路径长度最小,称这棵树为“最优二叉树”,有时也叫“赫夫曼树”或者“哈夫曼树”. 现给定若干权值,请构建一棵哈夫曼树,并输出各个权值对应的哈夫曼编码长度. 哈夫曼树中的结点定义如下: //哈夫曼树结点结构 typedef struct { int weight;//结点权重 int parent, left, right;//父结点.左孩子.右孩子在数组中的位置下标 }HTNode, *HuffmanTr

哈夫曼树(三)之 Java详解

前面分别通过C和C++实现了哈夫曼树,本章给出哈夫曼树的java版本. 目录 1. 哈夫曼树的介绍 2. 哈夫曼树的图文解析 3. 哈夫曼树的基本操作 4. 哈夫曼树的完整源码 转载请注明出处:http://www.cnblogs.com/skywang12345/ 更多内容:数据结构与算法系列 目录 哈夫曼树的介绍 Huffman Tree,中文名是哈夫曼树或霍夫曼树,它是最优二叉树. 定义:给定n个权值作为n个叶子结点,构造一棵二叉树,若树的带权路径长度达到最小,则这棵树被称为哈夫曼树. 这