思路:要使总费用最小,那么每次只选取最小长度的两块木板相加,再把这些“和”累加到总费用中即可;
第一种方法是通过最小堆建立哈夫曼树,然后通过遍历得到WPL,这也是浙大那本实验指导的思路,但是感觉极其繁琐,而且悲剧的是有两个数据大的情况出现异常,不知道怎么弄。
#include
#include
typedef struct treenode *Huffman;
struct treenode
{
int weight;
Huffman left;
Huffman right;
};
typedef struct heapnode *Heap;
struct heapnode
{
Huffman data;
int size;
};
Heap CreateHeap(int N)
{
Heap H;
int i;
H=malloc(sizeof(struct heapnode));
H->size=N;
H->data=malloc(sizeof(struct treenode)*(H->size+1));//之前我开的动态内存大小是H->size,应该是H->size+1,因为我第一个空间没有用,要注意!!!!怪不得造成程序异常退出。
for(i=1;i<=N;i++)
{
scanf("%d",&H->data[i].weight);
H->data[i].left=H->data[i].right=NULL;
}
return H;
}
Heap BuildMinHeap(Heap H)
{
int i,parent,child;
Huffman temp;
temp=malloc(sizeof(struct treenode));
for(i=H->size/2;i>0;i--)
{
*temp=H->data[i];
for(parent=i;parent*2<=H->size;parent=child)
{
child=parent*2;
if(child!=H->size&&H->data[child+1].weight<H->data[child].weight)
child++;
if(temp->weight<=H->data[child].weight)break;
else
H->data[parent]=H->data[child];
}
H->data[parent]=*temp;
}
return H;
}
Huffman DeleteMin(Heap H)
{
int parent,child;
Huffman Min,temp;
Min=malloc(sizeof(struct treenode));
temp=malloc(sizeof(struct treenode));
*Min=H->data[1]; //不能写成Min=&H->data[1]的形式,因为堆会调整,地址的内容会改变
*temp=H->data[H->size--];
for(parent=1;parent*2<=H->size;parent=child)
{
child=parent*2;
if(child!=H->size&&H->data[child+1].weight<H->data[child].weight)
child++;
if(temp->weight<H->data[child].weight)
break;
else
H->data[parent]=H->data[child];
}
H->data[parent]=*temp;
return Min;
}
void Insert(Heap H,Huffman item)
{
int i;
i=++H->size;
for(;i>1&&H->data[i/2].weight>item->weight;i=i/2)
H->data[i]=H->data[i/2];
H->data[i]=*item;
}
Huffman BuildHuffmanTree(Heap H,int N)
{
int i;
Huffman T;
for(i=1;i<N;i++)
{
T=malloc(sizeof(struct treenode));
T->left=DeleteMin(H);
T->right=DeleteMin(H);
T->weight=T->left->weight+T->right->weight;
Insert(H,T);
}
T=DeleteMin(H);
return T;
}
void Preorder(Huffman T,int *weight)
{
if(T->left!=NULL&&T->right!=NULL)
*weight=*weight+T->weight;
else
return;
Preorder(T->left,weight);
Preorder(T->right,weight);
}
int main()
{
Heap H;
int N,WPL;
Huffman T;
scanf("%d",&N);
H=CreateHeap(N);
H=BuildMinHeap(H);
T=BuildHuffmanTree(H,N);
WPL=0;
Preorder(T,&WPL);
printf("%d\n",WPL);
return 0;
}
#include
#include
#define MinData 0
typedef struct TreeNode* HuffmanTree;
struct TreeNode
{
int weight;
HuffmanTree Left;
HuffmanTree Right;
};
typedef struct HeapStruct *MinHeap;
struct HeapStruct{
HuffmanTree elements;
int size;
int capacity;
};
MinHeap MinHeap_Creat(int Maxsize);
MinHeap MinHeap_Build(int Maxsize);
void MinHeap_Insert(MinHeap H, HuffmanTree HT);
HuffmanTree MinHeap_Delete(MinHeap H);
HuffmanTree HuffmanTree_Build(MinHeap H);
void Get_wpl(HuffmanTree HT, int *wpl, int layer);
int main()
{
MinHeap H;
HuffmanTree T;
int N,wpl,depth;
scanf("%d",&N);
H=MinHeap_Build(N);
T=HuffmanTree_Build(H);
wpl=0;
depth=0;
Get_wpl(T,&wpl,depth);
printf("%d\n",wpl);
return 0;
}
MinHeap MinHeap_Creat(int MaxSize)//创建一个空堆
{
MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
H->elements = (HuffmanTree)malloc(sizeof(struct TreeNode)*(MaxSize + 1));//因为elemens[0]作为哨兵,从[1]开始存放,所以分配MaxSize+1空间
H->size = 0;
H->capacity = MaxSize;
H->elements[0].weight = MinData;//将elements[0]作为哨兵
return H;
}
MinHeap MinHeap_Build(int Maxsize) //建立一个最小堆
{
int *weight,i;
MinHeap H = MinHeap_Creat(Maxsize);
HuffmanTree Temp = (HuffmanTree)malloc(sizeof(struct TreeNode));
weight=malloc(sizeof(int)*Maxsize);
for(i=0;iscanf("%d",weight+i);
for (i = 0; i < Maxsize; ++i)
{
Temp->weight = weight[i];
Temp->Left = NULL;
Temp->Right = NULL;
MinHeap_Insert(H, Temp);
}
free(Temp);
return H;
}
void MinHeap_Insert(MinHeap H, HuffmanTree HT)
{
int i;
if(H->size == H->capacity)
return;
i = ++H->size;//i指向插入后堆中的最后一个元素的位置
for(; H->elements[i/2].weight > HT->weight; i/=2) //比较插入的结点和其父结点的大小
H->elements[i].weight = H->elements[i/2].weight;
H->elements[i] = *HT;
}
HuffmanTree MinHeap_Delete(MinHeap H)
{
HuffmanTree Temp, MinNode;
int Parent, Child;
if(H->size == 0)
return NULL;
MinNode = (HuffmanTree)malloc(sizeof(struct TreeNode));
Temp = (HuffmanTree)malloc(sizeof(struct TreeNode));
*MinNode = H->elements[1];//取出根结点的最小值
*Temp = H->elements[H->size--];//用最小堆的最后一个元素从根结点开始向上过滤下层结点
for(Parent = 1; Parent*2 <= H->size; Parent = Child){
Child = Parent*2;
if(Child != H->size && (H->elements[Child].weight > H->elements[Child+1].weight))
Child++;//当存在右子结点,且右子节点小于左子节点时,Child指向较小者
if(Temp->weight > H->elements[Child].weight)
H->elements[Parent] = H->elements[Child];//移动Temp到下一层
else
break;
}
H->elements[Parent] = *Temp;
free(Temp);
return MinNode;
}
HuffmanTree HuffmanTree_Build(MinHeap H)
{
HuffmanTree HT;
int i;
int times = H->size;//H->size的值会发生变化,所以要用另一个变量来存储
for (i = 1; i < times; ++i){//执行初始 H->size-1 次合并
HT = (HuffmanTree)malloc(sizeof(struct TreeNode));
HT->Left = MinHeap_Delete(H);
HT->Right = MinHeap_Delete(H);
HT->weight = HT->Left->weight + HT->Right->weight;
MinHeap_Insert(H, HT);
}
HT = MinHeap_Delete(H);
return HT;
}
void Get_wpl(HuffmanTree HT, int *wpl, int layer)
{
if(HT->Left == NULL && HT->Right == NULL)
*wpl += layer * HT->weight;
else{
Get_wpl(HT->Left, wpl, layer+1);
Get_wpl(HT->Right, wpl, layer+1);
}
}
第二种方法是我看别人的程序来的,其实根本不用堆和哈夫曼树这么复杂的数据结构,一个数组就可以搞定了。
http://blog.csdn.net/yjx_xx/article/details/39402223
这里写代码片#include
#include
int compare(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
}
int main()
{
int N,*a,sum,total,i,j;
scanf("%d",&N);
a=malloc(sizeof(int)*N);
for(i=0;iscanf("%d",a+i);
qsort(a,N,sizeof(int),compare);//将序列从小到大排序
sum=0;
total=0;
for(i=0;i1;i++)
{
sum=a[i]+a[i+1];//每次取出最小的两位
total=total+sum;//将和加入到总花费中
for(j=i+2;j//将sum的值插入到已排序的序列中
{
if(sum>a[j])
a[j-1]=a[j];
else
{
a[j-1]=sum;
break;
}
}
if(N==j)
a[j-1]=sum;
}
printf("%d\n",total);
return 0;
}