/*
【问题描述】已知输入一串正整数,正整数之间用空格键分开,请建立一个哈夫曼树,以输入的数字为叶节点,求这棵哈夫曼树的带权路径长度。【输入形式】首先输入正整数的个数,然后接下来为接下来的正整数,正整数个数不超过10个【输出形式】输出相应的权值【样例输入】5 4 5 6 7 8【样例输出】69
*/
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *leftchild,*rightchild; }BNode,*BTree; // 本题建立堆优化,使得每次提取元素时复杂度都为O(1),顺便练习一下堆的实现 int len; BTree heap[20]; void swap(BTree *a,BTree *b) { BTree tmp=*a; *a=*b; *b=tmp; } void push_heap(BTree *heap,BTree s) { heap[++len]=s; int t=len; while (t>1) { if (heap[t>>1]->data>heap[t]->data) { swap(&heap[t>>1],&heap[t]); } else return; } } BTree pop_heap(BTree *heap) { BTree re=heap[1],x; heap[1]=heap[len--]; int m=len>>1,t=1,k; while (t<=m) { k=t; if (heap[t<<1]->data<heap[t]->data) k=t<<1; if ((t<<1)+1<=len) if(heap[k]->data>heap[(t<<1)+1]->data) k=(t<<1)+1; if (k!=t) { swap(&heap[k],&heap[t]); t=k; } else return re; } return re; } void heap_adjust(BTree *heap,int pos,int end) { int i; BTree t=heap[pos]; for (i=2*pos;i<=end;i<<=1) { if (i<end && heap[i]->data<heap[i+1]->data) ++i; if (heap[pos]->data>heap[i]->data) break; heap[pos]=heap[i]; pos=i; } heap[pos]=t; } void sort_heap(BTree *heap) { int i; BTree t; for (i=len/2;i>0;i--) heap_adjust(heap,i,len); for (i=len;i>1;i--) { swap(&heap[1],&heap[i]); heap_adjust(heap,1,i-1); } } int main() { BTree root,lchild,rchild; scanf("%d",&len); int i; int ans=0; for (i=1;i<=len;++i) { heap[i]=(BTree)malloc(sizeof(BNode)); scanf("%d",&heap[i]->data); } sort_heap(heap); // Creat Heap while (len>1) { lchild=pop_heap(heap); rchild=pop_heap(heap); root=(BTree)malloc(sizeof(BNode)); //Pop two BTree and Mix Up root->data=lchild->data+rchild->data; ans+=root->data; root->leftchild=lchild; root->rightchild=rchild; push_heap(heap,root); } root=pop_heap(heap); //Find the Root of the tree printf("%d\n",ans); //Output //system("pause"); }
貌似是对的。哈夫曼树的路径长度——堆优化
最新推荐文章于 2024-08-07 15:31:00 发布