您的位置首页百科问答

C语言:背包问题(数据结构)

C语言:背包问题(数据结构)

详细程序代码如下:

用VC6.0编译.保存代码时,以.C为后缀名

下面是一组测试数据:

请输入背包能容纳的最大重量:20

请输入物品个数:10

请输入每一个物品的重量和价值:1,11,2,22, 3,33.....10,100

结果是正确的.

#include

#include

#include

#define NUMBER 20/*最大物品数量*/

#define TRUE 1

#define FALSE 0

struct Record/*本结构体用于保存每一次结果*/

{

int totalWeight;/*本次结果的总价值*/

int goods[NUMBER];/*本次结果对应的下标*/

struct Record *next;

};

struct Record *headLink;

struct Record result;

int stack[NUMBER];

int top;

int weight[NUMBER];/*保存物品重量的数组*/

int value[NUMBER];/*保存对应(下标相同)物品的价值*/

int knapproblen(int n,int maxweight,int weight[]);

void CreateHeadLink(void);

struct Record *MallocNode(void);

void InsertOneNode(struct Record *t);

void GetResult(void);

void ShowResult(void);

void main()

{

int n,i;

int maxWeight;/*背包能容纳的最大重量*/

printf("请输入背包能容纳的最大重量:\n");

scanf("%d",&maxWeight);

printf("请输入物品个数:\n");

scanf("%d",&n);

printf("请输入每一个物品的重量和价值:\n");

for(i=0;i

{

printf("请输入第%d个物品重量\n",i+1);

scanf("%d",&(weight[i]));

printf("请输入第%d个物品价值\n",i+1);

scanf("%d",&(value[i]));

}

if(knapproblen(n,maxWeight,weight)==TRUE)/*调用背包处理函数,如果成功就输出“答案”*/

{

GetResult();/*遍历链表,查找最佳的结果*/

ShowResult();/*显示结果*/

}

free(headLink);

getch();

}

/*调用背包处理函数*/

int knapproblen(int n,int maxweight,int weight[])

{

struct Record *p;

int i=1,j;

int tempTop=0;

top=0;/*先赋栈指针为0*/

CreateHeadLink();/*先建立链头*/

while((maxweight>0)&&(i<=n))/*当还可以装下物品,且物品没有用完时*/

{

if((maxweight-weight[i]==0)||(maxweight-weight[i]>0)&&(i

{

stack[++top]=i;/*把对应物品的处标保存到栈中*/

p=MallocNode();/*每一次得到一个结果后,就将该结果保存到链表中*/

for(tempTop=top,j=0;tempTop>0;tempTop--,j++)

{

p->totalWeight+=value[stack[tempTop]];/*得到本次结果的总价值*/

p->goods[j]=stack[tempTop];/*得到本次结果对应的物品下标*/

}

InsertOneNode(p);/*加到链表中*/

maxweight=maxweight-weight[i];

}

if(maxweight==0)/*能装入包中*/

{

return TRUE;

}

else if((i==n)&&(top>0))/*继续测试*/

{

i=stack[top];

top=top-1;

maxweight=maxweight+weight[i];

}

i++;

}

return FALSE;

}

/************************************

函数功能:建立链表表头

************************************/

void CreateHeadLink(void)

{

struct Record *p;

p=(struct Record*)malloc(sizeof(struct Record));

headLink=p;

p->next=NULL;

}

/************************************

函数功能:申请一个新结点,并将其初始化

************************************/

struct Record *MallocNode(void)

{

struct Record *p;

int i;

p=(struct Record*)malloc(sizeof(struct Record));

if(p==NULL)

return NULL;

p->totalWeight=0;/*初始化总价值为0*/

for(i=0;i

p->goods[i]=-1;/*初始化下标为-1,即无效*/

p->next=NULL;

return p;

}

/************************************

函数功能:在链表的结尾处增加一个结点

************************************/

void InsertOneNode(struct Record *t)

{

struct Record *p;

p=headLink;

while(p->next)

{

p=p->next;

}

p->next=t;

}

/************************************

函数功能:遍历链表,找总价值最大的结点保存到

result中

************************************/

void GetResult(void)

{

struct Record *p;

int i;

result.totalWeight=headLink->next->totalWeight;/*先将第一个结点当作"最佳"结果*/

for(i=0;i

{

if(headLink->next->goods[i]==-1)

break;

result.goods[i]=headLink->next->goods[i];

}

p=headLink->next->next;

while(p)/*查找最佳结果*/

{

if(p->totalWeight>result.totalWeight)/*如果发现p点价值比当前结果还大,则将p又作为最佳结果*/

{

result.totalWeight=p->totalWeight;

for(i=0;i

result.goods[i]=-1;

for(i=0;i

{

if(p->goods[i]==-1)

break;

result.goods[i]=p->goods[i];

}

}

p=p->next;

}

}

/***************************

显示最佳结果

*******************************/

void ShowResult(void)

{

int i;

printf("最佳装载如下:\n");

for(i=0;i

{

if(result.goods[i]==-1)

break;

printf("weight[%d]=%d\tvalue[%d]=%d\t",result.goods[i],weight[result.goods[i]],result.goods[i],value[result.goods[i]]);

if((i+1)%2==0)

printf("\n");

}

printf("\n总价值是:\n%d",result.totalWeight);

}