一、 实验目的和要求

1、掌握贪心算法的基本思想。
2、学习利用贪心算法设计和实现算法的方法。
3、了解利用替换法证明贪心策略是否能获得全局最优解的过程。
4、熟练掌握贪心算法在两个典型图搜索中的应用,即单源最短路径和最小生成树算法中,利用合理的数据结构优化算法复杂度的技巧。

二、实验任务

1、问题描述:利用贪心法来设计并实现最优装载问题
2、问题描述:利用贪心法来设计并实现单源最短路径。
3、问题描述:字符a~h出现的频率恰好是前n个Fibonacci数,它们的哈夫曼编码是什么?扩展到前n个字符的频率恰好是前n个Fibonacci数的情形。写程序实现。

三、实验内容及步骤

1.贪心法来设计并实现最优装载问题

问题描述:有一批集装箱要装上一艘载重量为C的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。

#include<stdio.h>
int main(){int n = 0; int max_weight;scanf("%d",&max_weight);    //输入轮船的载重量 scanf("%d",&n);                //输入集装箱的数量 int a[n] = {0};for(int i = 0;i < n; i++){ //将每个集装箱的重量存入数组a[n]中 scanf("%d",&a[i]);}for(int i= 0;i < n; i++){   //用冒泡排序将货物从小到大排列for(int j = 0;j < i;j++){if(a[j]>a[j+1]){int temp = 0;temp = a[j+1];a[j+1] = a[j];a[j] = temp;}}}int b[n] = {0};               //用数组b[n]记录能装入轮船的集装箱 for(int i = 0;i < n;i++){max_weight = max_weight - a[i];    if(max_weight > 0){  //还大于零就代表轮船还能继续装集装箱 b[i] = a[i];       //装进一个,数组b就记录一个 } }for(int i = 0;i < n; i++){if(b[i] != 0){printf("%d ",b[i]);}}}

2.贪心法来设计并实现单源最短路径

//【贪心算法】单源最短路径问题
#include <iostream>
using namespace std;#define N 5     // 5个顶点,1、2、3、4、5
#define M 9999  // maxint,大整数void Dijkstra(int n, int v, int dist[], int prev[], int c[][N + 1]);
void Traceback(int v, int i, int prev[]);int main()
{int v = 1;            // 源点为1int dist[N + 1];    // 从源到顶点i的最短特殊路径长度int   prev[N + 1];   // 从源到顶点i的最短路径上前一个顶点// 带权有向图的邻接矩阵,行和列下标从1开始int c[N + 1][N + 1] = {{M, M,  M,  M,  M,  M   },{M,   M,  10, M,  30, 100 },{M,   M,  M,  50, M,  M   },{M,   M,  M,  M,  M,  10  },{M,   M,  M,  20, M,  60  },{M,   M,  M,  M,  M,  M   },};// “输入”:带权有向图cout << "带权有向图的邻接矩阵为:\n";for (int i = 1; i <= N; i++){for (int j = 1; j <= N; j++)cout << c[i][j] << "\t";cout << endl;}// Dijkstra算法Dijkstra(N, v, dist, prev, c);// 输出cout << "源点1到顶点5的最短路径长度为:" << dist[5];cout << ",路径为:";Traceback(1, 5, prev);cout << endl;return 0;
}void Dijkstra(int n, int v, int dist[], int prev[], int c[][N + 1])
{bool s[N + 1];    // 顶点集合sfor (int i = 1; i <= n; i++){dist[i] = c[v][i]; // 从源到顶点i的最短特殊路径长度s[i] = false;if (dist[i] == M)prev[i] = 0;    // 从源到顶点i的最短路径上前一个顶点elseprev[i] = v;}dist[v] = 0;s[v] = true;for (int i = 1; i < n; i++){int temp = M;        // int u = v;          // 上一顶点// 找到具有最短特殊路长度的顶点ufor (int j = 1; j <= n; j++){if ((!s[j]) && (dist[j] < temp)){u = j;temp = dist[j];}}s[u] = true;// 更新dist值for (int j = 1; j <= n; j++){if ((!s[j]) && (c[u][j] < M)){int newdist = dist[u] + c[u][j];if (newdist < dist[j]){dist[j] = newdist;prev[j] = u;}}}}
}//输出最短路径 v源点,i终点,
void Traceback(int v, int i, int prev[])
{// 源点等于终点时,即找出全部路径if (v == i){cout << i;return;}Traceback(v, prev[i], prev);cout << "->" << i;
}

3.哈夫曼编码与Fibonacci结合

问题描述:字符a~h出现的频率恰好是前n个Fibonacci数,它们的哈夫曼编码是什么?扩展到前n个字符的频率恰好是前n个Fibonacci数的情形。写程序实现。

/*字符a~h出现的频率恰好是前n个Fibonacci数,它们的哈夫曼编码是什么?
扩展到前n个字符的频率恰好是前n个Fibonacci数的情形。写程序实现。*/
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int fib(int i){     /*斐波那契函数改进,此函数能得到第n个数的斐波那契函数的值*/int j,a,b,c;int shuzu[i]={0};a=1;b=1;  /* 前两项已知为1,直接输出  */if(i<3){return 1;}else{for(j=2;j<i;j++)      {c=a+b;   /* 前两项相加   */shuzu[j]=c;a=b;b=c;    }return shuzu[i-1];}
}
struct HTreeNode{int parent;int lchild;int rchild;int weight;
};
struct HTree{struct HTreeNode *body;        /*定义一个指向结构体 HTreeNode 的指针 body */int length;
};
struct HTree *iniHTree(int num){/*对哈夫曼树初始化*/struct HTree *ht;           /*定义一个指向结构体 HTree 的指针 ht */ ht=(struct HTree *)malloc(sizeof(struct HTree));  /*创建一个 struct HTree 结构体大小的空间,然后强制转换为struct HTree * 类型的指针,最后赋值给ht,此时ht指向一个 struct HTree 结构体大小的新空间 */ int size=2*num-1;ht->body=(struct HTreeNode *)malloc(sizeof(struct HTreeNode)*size);ht->length=0;int i;for(i=0;i<num;i++){ht->body[i].parent=-1;ht->body[i].lchild=-1;ht->body[i].rchild=-1;int temp;temp=fib(i+1);printf("The %dth weight= %d \n",i,fib(i+1));ht->body[i].weight=temp;ht->length++;}for(;i<size;i++){ht->body[i].parent=-1;ht->body[i].lchild=-1;ht->body[i].rchild=-1;ht->body[i].weight=pow(2,31)-1;}return ht;
}
void show(struct HTree *ht){/*打印哈夫曼树*/if(ht->body!=NULL){for(int i=0;i<ht->length;i++){printf("%4d",ht->body[i].lchild);printf("%4d",ht->body[i].weight);printf("%4d",ht->body[i].rchild);printf("%4d",ht->body[i].parent);printf("\n");}}
}
void findTwoMinHTNode(struct HTree *ht,int *min1,int *min2){int m1,m2;int minWeight;int j=0;while(ht->body[j].parent!=-1){j++;}m1=j;minWeight=ht->body[m1].weight;for(int i=m1+1;i<ht->length;i++){if(ht->body[i].parent==-1&&ht->body[i].weight<minWeight){m1=i;minWeight=ht->body[i].weight;}}ht->body[m1].parent=1;*min1=m1;j=0;while(ht->body[j].parent!=-1){j++;}m2=j;minWeight=ht->body[m2].weight;for(int i=m2+1;i<ht->length;i++){if(ht->body[i].parent==-1&&ht->body[i].weight<minWeight){m2=i;minWeight=ht->body[m2].weight;}}*min2=m2;ht->body[m2].parent=1;
}
void consummateHT(struct HTree *ht,int num){/*完善哈夫曼树*/if(ht==NULL){printf("HT is not exit\n");return;}int min1,min2;for(int i=num;i<2*num-1;i++){findTwoMinHTNode(ht,&min1,&min2);ht->body[min1].parent=i;ht->body[min2].parent=i;ht->body[i].lchild=min1;ht->body[i].rchild=min2;ht->body[i].weight=ht->body[min1].weight+ht->body[min2].weight;ht->length++;}
}
void codeHT(struct HTree *ht){/*哈夫曼编码核心代码*/int count=(ht->length+1)/2;int weightdata[count];for(int i=0;i<count;i++){weightdata[i]=ht->body[i].weight;}char *ch[count];char a[count];int index=0;for(int i=0;i<ht->length;i++){ht->body[i].weight=0;}int cur=ht->length-1;while(cur!=-1){if(ht->body[cur].weight==0){/*weight为0表示没有被访问过*/ht->body[cur].weight=1;/*weight为1表示左子树被访问过*/if(ht->body[cur].lchild!=-1){/*左孩子不等于-1说明还在中间节点,cur继续往左走,编码左0右1,所以编为0*/a[index++]='0';cur=ht->body[cur].lchild;}else{/*当前节点的左孩子为-1说明遍历到头了,当前节点的完整编码就存在数组a中*/a[index]='\0';ch[cur]=(char *)malloc(sizeof(char)*count);strcpy(ch[cur],a);/*对编码拷贝*/}}else if(ht->body[cur].weight==1){/*weight为1表示右子树没被访问过*/ht->body[cur].weight=2;/*weight为2表示左右子树都被访问过*/if(ht->body[cur].rchild!=-1){/*右孩子孩子不等于-1说明还在中间节点,cur继续往右走,编码左0右1,所以编为1*/a[index++]='1';cur=ht->body[cur].rchild;}/*右孩子为-1时说明遍历到头了,由于之前编码已经拷贝过了,所以直接跳过,不做处理*/}else{/*weight为2说明左右都访问过,回退到父节点,并将索引下标减一,相当于删掉数组中最后一个字符*/ht->body[cur].weight=0;cur=ht->body[cur].parent;index--;}}printf("最优前缀码:\n");for(int i=0;i<count;i++){printf("权重为%d的编码:%s\n",weightdata[i],ch[i]);}
}int main(){struct HTree *ht;int num;printf("leaf=");scanf("%d",&num);ht=iniHTree(num);consummateHT(ht,num);printf("哈夫曼树存储表如下:\n");show(ht);printf("\n");codeHT(ht);return 0;
}

注:其中的关于哈夫曼编码的代码参考了此博客 哈夫曼编码代码实现(C语言)

四.实验心得

自己写!!!

算法设计与分析 实验三 贪心算法相关推荐

  1. 算法设计与分析 实验二 贪心算法

    实验2.<贪心算法实验> 一.实验目的 了解贪心算法思想 掌握贪心法典型问题,如背包问题.作业调度问题等. 二.实验内容 编写一个简单的程序,实现单源最短路径问题. 编写一段程序,实现找零 ...

  2. 算法设计与分析 实验三 动态规划算法

    实验3.<动态规划算法实验> 一.实验目的 掌握动态规划方法贪心算法思想 掌握最优子结构原理 了解动态规划一般问题 二.实验内容 编写一个简单的程序,解决0-1背包问题.设N=5,C=10 ...

  3. 算法设计与分析 实验三 回溯法求解地图填色问题

    回溯法求解地图填色问题 一.实验目的与要求 1.实验基本要求: 2.实验亮点: 二.实验内容与方法 三.实验步骤与过程 1.未优化的回溯: (1)算法描述: (2)编程实现 (3)运行并测试: 2.对 ...

  4. 算法设计与分析 - 磁带存储程序 - 贪心算法(java实现)

    题目描述: 设有n个程序{1,2,...,n}要存放在长度为L的磁带上.程序i存放在磁带上的长度是li,1<=i<=n. 程序存储问题要求确定这n个程序在磁带上的一个存储方案,使得能够在磁 ...

  5. 太原理工大学linux与python编程r实验报告_太原理工大学算法设计与分析实验报告...

    <太原理工大学算法设计与分析实验报告>由会员分享,可在线阅读,更多相关<太原理工大学算法设计与分析实验报告(12页珍藏版)>请在人人文库网上搜索. 1.本科实验报告课程名称: ...

  6. 算法设计与分析实验指导(完整版)

    算法设计与分析实验指导 文章目录 算法设计与分析实验指导 1. 快速排序及第k小数 1.1 快速排序 1.1.1 Implementation 1 1.1.2 算法特性分析 1.1.3 Improve ...

  7. 格雷码算法c语言实验报告,算法设计与分析实验报告

    本科生实验报告 课程名称:算法设计与分析 实验项目:递归和分治算法 实验地点:计算机系实验楼110 专业课:物联网1601学生.2016002105 学生姓名:于 指导员:郝晓丽 2018年5月4日 ...

  8. C/C++ 算法设计与分析实验报告

    算法设计与分析实验报告 算法实验整体框架的构建 菜单代码块 选择函数代码块 主函数代码块 实验模块Ⅰ:算法分析基础--Fibonacci序列问题 实验解析 Fibonacci序列问题代码块 实验模块Ⅱ ...

  9. 深大算法设计与分析实验二——分治法求最近点对问题

    源代码: 深大算法设计与分析实验二--分治法求最近点对问题代码-C/C++文档类资源-CSDN下载 目录 实验问题 一.实验目的: 二.内容: 三.算法思想提示 产生不重复的随机点算法: 蛮力算法: ...

最新文章

  1. 果断收藏!一张版图带你摸清全球10大自动驾驶联盟布局
  2. React组件通信技巧
  3. activiti监听器使用
  4. Matlab | MATLAB实现图像的水印去除
  5. First java program
  6. lua 字符串分割_Lua 分隔字符串,可以设置指定分隔符
  7. 通过端到端的数据侦测提升QoS
  8. 正反案例介绍SOLID原则
  9. 预防和检测如日中天?事件响应表示不服
  10. jenkins日志乱码linux,Jenkins控制台中乱码问题解决
  11. linux运维需要掌握的基础知识
  12. 美国航空航天和国防承包商在瑞士采用区块链进行供应链管理
  13. 哟,2020 年了,用 Vue 做一个自己的小程序吧!| 原力计划
  14. BZOJ 1146 网络管理Network(树链剖分+BST)
  15. qpsk matlab仿真,qpsk的matlab和simulink仿真.pdf
  16. linux修改内核logo,Linux内核开发-修改开机Logo
  17. 基于Python的动漫人物分类识别系统
  18. 你知道各调的特点吗?
  19. U盘 如何自定义U盘图标并彻底隐藏配置文件
  20. Winform(XtraReport)实现打印方法(转载)(只是自我参考有错误的地方欢迎各位大佬前来交流心得)...

热门文章

  1. 从0开始手写一个 SpringMVC 框架,向高手进阶!
  2. 用Qt写一个简单的音乐播放器(七):界面美化(QSS样式表)
  3. 在线教育行业 12 大核心场景案例全解析!
  4. TP-Link 不回应,安全工程师公开了其路由器漏洞
  5. 允许Traceroute探测漏洞解决方法
  6. Dask简介(python)
  7. 距离度量 —— 欧式距离(Euclidean Distance)
  8. 大数据发展面临七个挑战
  9. 【100%通过率】华为OD机试真题 JavaScript 实现【打印机队列】【2023 Q1 | 100分】
  10. springboot 使用工厂模式+策略模式替代多重if 案例