11:36:53 2019-08-30

学习

 09:42:25 2019-08-31

补完昨天未写完的并查集优化

 

带权路径长度(WPL) (Weighted Path Length of Tree),设二叉树有n个叶子节点,每个叶子节点带有权值${w_k}$,从根节点到每个叶子节点的长度为${l_k}$,则每个叶子节点的带权路径长度之和就是:${WPL}=\displaystyle \sum_{k=1}^n{w_k}{l_k}$

 

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

哈夫曼树的构造:每次把权值最小的两课二叉树合并

 

利用最小堆 实现哈夫曼树:

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 
  4 typedef struct TreeNode* HuffmanTree;
  5 struct TreeNode
  6 {
  7     int Weight;    //权重
  8     HuffmanTree Right, Left;
  9 };
 10 typedef struct HeapStruct* MinHeap;
 11 struct HeapStruct
 12 {
 13     HuffmanTree* Elements;
 14     int Capacity;
 15     int Size;
 16 };
 17 
 18 MinHeap Create(int MaxSize);   //创造一个空的最小堆
 19 int IsFull(MinHeap H);
 20 void Insert(MinHeap H, HuffmanTree T);
 21 HuffmanTree DeleteMin(MinHeap H);   //删除一个权重最小的节点 并返回
 22 
 23 MinHeap Create(int MaxSize)
 24 {
 25     MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
 26     H->Elements = (HuffmanTree*)malloc(sizeof(struct TreeNode) * (MaxSize + 1));
 27     H->Capacity = MaxSize;
 28     H->Size = 0;
 29     H->Elements[0]->Weight = -1;  //设置哨兵
 30     return H;
 31 }
 32 int IsFull(MinHeap H)
 33 {
 34     return (H->Size == H->Capacity) ? 1 : 0;
 35 }
 36 void Insert(MinHeap H, HuffmanTree T)
 37 {
 38     if (IsFull(H))
 39         return;
 40     int i = ++H->Size;
 41     for (; T->Weight < H->Elements[i / 2]->Weight; i /= 2)
 42         H->Elements[i] = H->Elements[i / 2];
 43     H->Elements[i] = T;
 44 }
 45 HuffmanTree DeleteMin(MinHeap H)
 46 {
 47     if (IsFull(H))
 48         return;
 49     HuffmanTree MinItem = H->Elements[1];
 50     HuffmanTree Tmp = H->Elements[H->Size--];
 51     int Parent, Child;   //这俩个记录的是位置
 52     for (Parent = 1; Parent * 2 <= H->Size; Parent = Child)
 53     {
 54         Child = Parent * 2;
 55         if (Child != H->Size && H->Elements[Child]->Weight > H->Elements[Child + 1]->Weight)
 56             Child++;
 57         if (Tmp->Weight <= H->Elements[Child]->Weight)break;   //注意这边  找到后就立即结束循环 这样才能添加到正确位置
 58         else
 59             H->Elements[Parent] = H->Elements[Child];
 60     }
 61     H->Elements[Parent] = Tmp;
 62     return MinItem;
 63 }
 64 
 65 //建立最小堆
 66 //元素已经读入
 67 void PercDown(MinHeap H, int i)
 68 {
 69     int Parent, Child;
 70     HuffmanTree Tmp = H->Elements[i];
 71     for (Parent = i; Parent * 2 <= H->Size; Parent = Child)
 72     {
 73         Child = Parent * 2;
 74         if ((Child != H->Size) && (H->Elements[Child]->Weight > H->Elements[Child + 1]->Weight))
 75             Child++;
 76         if (Tmp->Weight <= H->Elements[Child]->Weight)break;
 77         else
 78             H->Elements[Parent] = H->Elements[Child];    
 79     }
 80     H->Elements[Parent] = Tmp;
 81 }
 82 void BuildMinHeap(MinHeap H)
 83 {
 84     for (int i = H->Size / 2; i > 0; i--)   //从最后一个有子节点的父节点开始
 85         PercDown(H, i);
 86 }
 87 
 88 //利用最小堆 构建哈夫曼树 
 89 //每次把权值最小的两颗二叉树合并
 90 HuffmanTree Huffman(MinHeap H)
 91 { //假设H->Size个权值已经存在H->Elements[]->Weight里
 92     int i;
 93     HuffmanTree T;
 94     BuildMinHeap(H);  //将H->Elements[]按照权重调整为最小堆
 95     for (int i = 1; i < H->Size; i++)   //H->Size个元素合并 总共需要H->Size-1次
 96     {
 97         T = (HuffmanTree)malloc(sizeof(struct TreeNode));
 98         T->Left = DeleteMin(H);  //取出权重最小的元素 作为T的左节点
 99         T->Right = DeleteMin(H); //取出权重最小的元素 作为T的右节点
100         T->Weight = T->Left->Weight + T->Right->Weight;  //计算新的权重
101         Insert(H, T);  //将新T插入最小堆中;
102     }
103     T = DeleteMin(H);
104     return T;
105 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-04-08
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案