5-29 修理牧场

这里写图片描述
思路:要使总费用最小,那么每次只选取最小长度的两块木板相加,再把这些“和”累加到总费用中即可;
第一种方法是通过最小堆建立哈夫曼树,然后通过遍历得到WPL,这也是浙大那本实验指导的思路,但是感觉极其繁琐,而且悲剧的是有两个数据大的情况出现异常,不知道怎么弄。

#include<stdio.h>
#include<stdlib.h>
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 <stdio.h>  
#include <stdlib.h>  

#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;i<Maxsize;i++)
        scanf("%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<stdio.h>
#include<stdlib.h>
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;i<N;i++)
        scanf("%d",a+i);
    qsort(a,N,sizeof(int),compare);//将序列从小到大排序
    sum=0;
    total=0;
    for(i=0;i<N-1;i++)
    {
        sum=a[i]+a[i+1];//每次取出最小的两位
        total=total+sum;//将和加入到总花费中
        for(j=i+2;j<N;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;
}
  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值