排序算法比较实验报告
信息学部算法分析
上机报告
学号0901******** 姓名陈龙
指导老师秦明
时间2011.11.1~11.23
一.上机实验题目
实验1
比较归并排序和快速排序的区别。
实验2
利用贪心算法对背包问题进行求解。
二.算法设计思路
归并排序:
申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列,设定两个指针,最初位置分别为两个已经排序序列的起始位置,比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置,重复步骤直到某一指针达到序列尾,将另一序列剩下的所
有元素直接复制到合并序列尾。
快速排序:
设置两个变量I、J,排序开始的时候:I=0,J=N-1;以第一个数组元素作为关键数据,赋值给key,即key=A[0];从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;重复第3、4、5步,直到I=J;(3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。找到并交换的时候i,j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。)
背包问题:
用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 。可以压缩空间,f[v]=max{f[v],f[v-c[i]]+w[i]}
三. 源程序
归并排序
#include
#include
# define N 50
int b[N],a[N];
int n,i;
void Merge (int low, int mid,int high) //合并
{
int i; int l=low,h=mid+1,k=l;
while ((l<=mid) && (h<=high)) //部分合并
{
if (a[l]<=a[h]) b[k++]=a[l++];
else b[k++]=a[h++];
}
if(l>mid)
while (h<=high) b[k++]=a[h++]; //转储剩余部分 else
while(l<=mid) b[k++]=a[l++];
for (i=0;i<=high;i++) //将b数组转储到a a[i]=b[i];
}
int Merge2 (int l,int h) //分类
{
for (i=0;i printf("%d ",a[i]); printf("\n"); int m; if (l { m=(l+h)/2; Merge2(l, m); Merge2(m+1, h); Merge ( l,m,h); } return a[i]; } void main() { printf("请输入您要排序的数组大小(不超过50):"); while (scanf("%d",&n)!=EOF) { for (i=0;i scanf("%d",&a[i]); Merge2(0,n-1); for (i=0;i printf("%d ",a[i]); printf("%d\n",a[n-1]); } } 快速排序 #include "stdio.h" #include "stdlib.h" # define N 50 int a[N]; int i,n; void Quick(int list[ ], int left, int right) //lfet为数组最左端, right为数组最右端{ int s; int i, j; int temp; for (i=0;i printf("%d ",a[i]); printf("\n"); if(left < right) //如果没有查询完所有数组,则继续递归{ s = list[left]; i = left-1; j = right + 1; while(i+1!=j) { if(list[i+1]<=s) i++; else if(list[j-1]>s) j--; else { temp=list[i+1]; list[++i]=list[j-1]; list[--j]=temp; } } list[left] = list[i]; list[i] = s; Quick(list, left, i - 1); //对左边递归 Quick(list, i + 1, right); //对右边递归} } void main() { printf("请输入您要排序的数组大小(不超过50):"); while (scanf("%d",&n)!=EOF) { for (i=0;i scanf("%d",&a[i]); Quick(a,0,n-1); for (i=0;i printf("%d ",a[i]); printf("%d\n",a[n-1]); } } 背包问题 #include #include #define N 3 struct Thing { int num ; int price; int weight; float aver; }; void swap(int *i,int *j) { int temp; temp = *i; *i = *j; *j = temp; } int main() { int M; int i,j,k=0,NUM = 1; struct Thing *p = (struct Thing *)malloc(N*sizeof(struct Thing)); printf("请输入背包能承受的重量:"); scanf("%d",&M); printf("\n"); for(i=0;i { // printf("请输入物品序列号(请从1开始顺序加1):"); // scanf("%d",&p[i].num); p[i].num = NUM++; printf("请输入%d号物品的价值:",p[i].num); scanf("%d",&p[i].price); printf("请输入%d号物品的重量:",p[i].num); scanf("%d",&p[i].weight); p[i].aver = ((float)p[i].price / (float)p[i].weight); } for(i = 0;i { for(j = i+1;j { if(p[i].aver { swap(&p[i].num,&p[j].num); swap(&p[i].price,&p[j].price); swap(&p[i].weight,&p[j].weight); } } } printf("\n"); printf("按照物品单位重量的价值从大到小排序为:\n"); for(i = 0;i { printf("事件序列号:%d ",p[i].num); printf("物品价值%d ",p[i].price); printf("物品重量%d ",p[i].weight); printf("\n"); } printf("\n"); printf("\n"); while(1) { if(M > p[k].weight) { printf("先装入%d号码的物品%d的重量,\n",p[k].num,p[k].weight); M = M - p[k].weight; k++; } else break; } printf("再装入%d号的物品%d的重量\n",p[k].num,M); printf("\n"); printf("\n"); free(p); return 0; } 三.实验结果 归并排序 快速排序 背包问题 五.实验心得 通过实验可以知道,若数据比较无序,快排快,若数据中部分有序,归并快。我觉得算法是一门理论和实践性都很强的课程,从算法和对算法的分析,几乎都是对具体问题的抽象。因而,我们需要更多的时间来理解、掌握相关的知识,并利用电脑在机子上运行敲打代码,吸收算法的精髓。当然在这一过程中也存在很多问题,比如我们不能完全理解算法,不能将之在上机实验中将之实现,对于算法的一些小细节不够清晰,影响了我们对算法的理解,但我觉得我们很幸运,因为秦老师在有限的课程中尽量将知识点以比较容易接受的方式给我们讲解,教我们用简单的方法理解记忆不同的知识,对于我们提出的问题,无论课上或是课外,老师一直是不厌其烦,甚至利用课余时间为我们讲解重要的难题。 《数据结构》实验报告排序实验题目: 输入十个数,从插入排序,快速排序,选择排序三类算法中各选一种编程实现。 实验所使用的数据结构内容及编程思路: 1. 插入排序:直接插入排序的基本操作是,将一个记录到已排好序的有序表中,从而得到一个新的,记录增一得有序表。 一般情况下,第i 趟直接插入排序的操作为:在含有i-1 个记录的有序子序列r[1..i-1 ]中插入一个记录r[i ]后,变成含有i 个记录的有序子序列r[1..i ];并且,和顺序查找类似,为了在查找插入位置的过程中避免数组下标出界,在r [0]处设置哨兵。在自i-1 起往前搜索的过程中,可以同时后移记录。整个排序过程为进行n-1 趟插入,即:先将序列中的第一个记录看成是一个有序的子序列,然后从第2 个记录起逐个进行插入,直至整个序列变成按关键字非递减有序序列为止。 2. 快速排序:基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。 假设待排序的序列为{L.r[s] ,L.r[s+1],…L.r[t]}, 首先任意选取一个记录 (通常可选第一个记录L.r[s])作为枢轴(或支点)(PiVOt ),然后按下述原则重新排列其余记录:将所有关键字较它小的记录都安置在它的位置之前,将所有关键字较大的记录都安置在它的位置之后。由此可以该“枢轴”记录最后所罗的位置i 作为界线,将序列{L.r[s] ,… ,L.r[t]} 分割成两个子序列{L.r[i+1],L.[i+2], …,L.r[t]}。这个过程称为一趟快速排序,或一次划分。 一趟快速排序的具体做法是:附设两个指针lOw 和high ,他们的初值分别为lOw 和high ,设枢轴记录的关键字为PiVOtkey ,则首先从high 所指位置起向前搜索找到第一个关键字小于PiVOtkey 的记录和枢轴记录互相交换,然后从lOw 所指位置起向后搜索,找到第一个关键字大于PiVOtkey 的记录和枢轴记录互相 交换,重复这两不直至low=high 为止。 具体实现上述算法是,每交换一对记录需进行3 次记录移动(赋值)的操作。而实际上, 算法设计与分析基础 实验报告 应用数学学院 二零一六年六月 实验一插入排序算法 一、实验性质设计 二、实验学时14学时 三、实验目的 1、掌握插入排序的方法和原理。 2、掌握java语言实现该算法的一般流程。 四、实验内容 1、数组的输入。 2、输入、输出的异常处理。 3、插入排序的算法流程。 4、运行结果的输出。 五、实验报告 Ⅰ、算法原理 从左到右扫描有序的子数组,直到遇到一个大于(或小于)等于A[n-1]的元素,然后就把A[n-1]插在该元素的前面(或后面)。 插入排序基于递归思想。 Ⅱ、书中源代码 算法InsertionSort(A[0..n-1]) //用插入排序对给定数组A[0..n-1]排序 //输入:n个可排序元素构成的一个数组A[0..n-1] //输出:非降序排列的数组A[0..n-1] for i ←1 to n-1 do v ← A[i] j ← i-1 while j ≥0and A[j] > v do A[j+1] ← A[j] j ← j-1 A[j+1] ← v Ⅲ、Java算法代码: import java.util.*; public class Charu { public static void main(String[] args) { int n = 5; int a[] = new int[n]; int s = a.length; int i = 0, j = 0, v = 0; System.out.println("请输入若干个数字:"); Scanner sc = new Scanner(System.in); try { while (i < s) { a[i] = sc.nextInt(); i++; } for (i = 1; i 数据结构与算法设计 实验报告 (2016 — 2017 学年第1 学期) 实验名称: 年级: 专业: 班级: 学号: 姓名: 指导教师: 成都信息工程大学通信工程学院 一、实验目的 验证各种简单的排序算法。在调试中体会排序过程。 二、实验要求 (1)从键盘读入一组无序数据,按输入顺序先创建一个线性表。 (2)用带菜单的主函数任意选择一种排序算法将该表进行递增排序,并显示出每一趟排序过程。 三、实验步骤 1、创建工程(附带截图说明) 2、根据算法编写程序(参见第六部分源代码) 3、编译 4、调试 四、实验结果图 图1-直接输入排序 图2-冒泡排序 图3-直接选择排序 五、心得体会 与哈希表的操作实验相比,本次实验遇到的问题较大。由于此次实验中设计了三种排序方法导致我在设计算法时混淆了一些概念,设计思路特别混乱。虽然在理清思路后成功解决了直接输入和直接选择两种算法,但冒泡《数据结构》实验报告——排序.docx
插入排序算法实验报告
= 0 && a[j] > v) { a[j + 1] = a[j]; j--; } a[j + 1] = v; } System.out.println("插入排序结果显示:"); for (i = 0; i < s; i++) { System.out.println(a[i]); } } catch (Exception es) { System.out.println(es); } } } Ⅳ、运行结果显示:排序操作实验报告