算法分析与复杂性理论 实验报告 基本排序

合集下载

算法实验报告结果分析

算法实验报告结果分析

一、实验背景随着计算机科学技术的不断发展,算法作为计算机科学的核心内容之一,其重要性日益凸显。

为了验证和评估不同算法的性能,我们进行了一系列算法实验,通过对比分析实验结果,以期为后续算法研究和优化提供参考。

二、实验方法本次实验选取了三种常见的算法:快速排序、归并排序和插入排序,分别对随机生成的数据集进行排序操作。

实验数据集的大小分为10000、20000、30000、40000和50000五个级别,以验证算法在不同数据量下的性能表现。

实验过程中,我们使用Python编程语言实现三种算法,并记录每种算法的运行时间。

同时,为了确保实验结果的准确性,我们对每种算法进行了多次运行,并取平均值作为最终结果。

三、实验结果1. 快速排序快速排序是一种高效的排序算法,其平均时间复杂度为O(nlogn)。

从实验结果来看,快速排序在所有数据量级别下均表现出较好的性能。

在数据量较小的10000和20000级别,快速排序的运行时间分别为0.05秒和0.1秒;而在数据量较大的40000和50000级别,运行时间分别为0.8秒和1.2秒。

总体来看,快速排序在各个数据量级别下的运行时间均保持在较低水平。

2. 归并排序归并排序是一种稳定的排序算法,其时间复杂度也为O(nlogn)。

实验结果显示,归并排序在数据量较小的10000和20000级别下的运行时间分别为0.15秒和0.25秒,而在数据量较大的40000和50000级别,运行时间分别为1.5秒和2.5秒。

与快速排序相比,归并排序在数据量较小的情况下性能稍逊一筹,但在数据量较大时,其运行时间仍然保持在较低水平。

3. 插入排序插入排序是一种简单易实现的排序算法,但其时间复杂度为O(n^2)。

实验结果显示,插入排序在数据量较小的10000和20000级别下的运行时间分别为0.3秒和0.6秒,而在数据量较大的40000和50000级别,运行时间分别为8秒和15秒。

可以看出,随着数据量的增加,插入排序的性能明显下降。

排序算法设计实验报告

排序算法设计实验报告

一、实验目的1. 理解排序算法的基本原理和常用算法。

2. 通过编程实现几种常见的排序算法。

3. 分析不同排序算法的性能,比较其优缺点。

4. 培养编程能力和算法思维能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.73. 开发工具:PyCharm三、实验内容1. 算法选择:冒泡排序、选择排序、插入排序、快速排序、归并排序2. 实现排序算法3. 分析算法性能4. 比较不同排序算法的优缺点四、实验步骤1. 设计排序算法(1)冒泡排序冒泡排序是一种简单的排序算法,其基本思想是通过比较相邻元素的值,将较大的元素向后移动,较小的元素向前移动,直到整个序列有序。

(2)选择排序选择排序的基本思想是遍历整个序列,在未排序的序列中找到最小(大)元素,将其与序列的第一个元素交换,然后继续在剩余未排序的序列中找到最小(大)元素,重复此过程,直到整个序列有序。

(3)插入排序插入排序的基本思想是将未排序的序列中的元素插入到已排序的序列中,直到整个序列有序。

(4)快速排序快速排序是一种高效的排序算法,其基本思想是选取一个基准值,将序列分为两部分,一部分小于基准值,另一部分大于基准值,然后递归地对这两部分进行快速排序。

(5)归并排序归并排序是一种分治策略的排序算法,其基本思想是将序列划分为两个子序列,分别对这两个子序列进行排序,然后将排序好的子序列合并为一个有序序列。

2. 编写排序算法代码```pythondef bubble_sort(arr):n = len(arr)for i in range(n):for j in range(0, n-i-1):if arr[j] > arr[j+1]:arr[j], arr[j+1] = arr[j+1], arr[j]def selection_sort(arr):n = len(arr)for i in range(n):min_idx = ifor j in range(i+1, n):if arr[min_idx] > arr[j]:min_idx = jarr[i], arr[min_idx] = arr[min_idx], arr[i]def insertion_sort(arr):n = len(arr)for i in range(1, n):key = arr[i]j = i-1while j >= 0 and key < arr[j]:arr[j+1] = arr[j]j -= 1arr[j+1] = keydef quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) // 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quick_sort(left) + middle + quick_sort(right) def merge_sort(arr):if len(arr) <= 1:return arrmid = len(arr) // 2left = merge_sort(arr[:mid])right = merge_sort(arr[mid:])return merge(left, right)def merge(left, right):result = []i = j = 0while i < len(left) and j < len(right):if left[i] < right[j]:result.append(left[i])i += 1else:result.append(right[j])j += 1result.extend(left[i:])result.extend(right[j:])return result```3. 分析算法性能(1)冒泡排序冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。

算法实现与复杂度分析实习报告

算法实现与复杂度分析实习报告

算法实现与复杂度分析实习报告一、实习背景在计算机科学与技术领域中,算法的实现和复杂度分析是非常重要的一部分。

算法是计算机问题求解的方法和步骤的描述,是计算机科学的核心内容。

而复杂度分析则是对算法运行效率和资源消耗进行评估的方法。

在这次实习中,我主要学习了算法的实现和复杂度分析,并通过实际编程实践了解了不同算法的运行效率和资源利用。

二、实习过程1. 算法实现在实习的第一阶段,我学习了常见的排序算法和查找算法,并进行了实现。

其中包括冒泡排序、插入排序、选择排序、快速排序、归并排序等排序算法,以及顺序查找、二分查找等查找算法。

通过实现这些算法,我深入理解了它们的原理和思想,并通过编程实践加深了对算法的理解。

在实现算法的过程中,我注意到不同算法之间的差别。

例如,冒泡排序算法的时间复杂度为O(n^2),而快速排序算法的时间复杂度为O(nlogn)。

这表明快速排序算法在处理大规模数据时比冒泡排序算法更加高效。

同时,我还注意到了一些排序算法的稳定性,即算法在排序过程中是否能够保持相同元素的相对位置不变。

例如,冒泡排序是稳定的,而选择排序是不稳定的。

2. 复杂度分析在实现算法的基础上,我学习了如何对算法的复杂度进行分析。

复杂度分析主要关注算法的时间复杂度和空间复杂度。

时间复杂度表示算法解决问题所需的时间随输入规模的增长而增长的趋势。

通常使用大O记法来表示时间复杂度。

例如,O(n)表示算法的时间复杂度与输入规模成线性关系,O(n^2)表示算法的时间复杂度与输入规模成平方关系。

通过分析算法的循环次数、递归层数等特征,可以得出算法的时间复杂度。

空间复杂度表示算法解决问题所需的额外空间随输入规模的增长而增长的趋势。

同样使用大O记法表示空间复杂度。

例如,O(n)表示算法的空间复杂度与输入规模成线性关系,O(1)表示算法的空间复杂度为常数。

通过分析算法使用的额外数据结构、递归调用的深度等特征,可以得出算法的空间复杂度。

通过对算法的时间复杂度和空间复杂度进行分析,可以评估算法的运行效率和资源消耗。

算法设计与分析实验报告三篇

算法设计与分析实验报告三篇

算法设计与分析实验报告一实验名称统计数字问题评分实验日期2014 年11 月15 日指导教师姓名专业班级学号一.实验要求1、掌握算法的计算复杂性概念。

2、掌握算法渐近复杂性的数学表述。

3、掌握用C++语言描述算法的方法。

4.实现具体的编程与上机实验,验证算法的时间复杂性函数。

二.实验内容统计数字问题1、问题描述一本书的页码从自然数1 开始顺序编码直到自然数n。

书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。

例如,第6 页用数字6 表示,而不是06 或006 等。

数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2, (9)2、编程任务给定表示书的总页码的10 进制整数n (1≤n≤109) 。

编程计算书的全部页码中分别用到多少次数字0,1,2, (9)三.程序算法将页码数除以10,得到一个整数商和余数,商就代表页码数减余数外有多少个1—9作为个位数,余数代表有1—余数本身这么多个数作为剩余的个位数,此外,商还代表1—商本身这些数出现了10次,余数还代表剩余的没有计算的商的大小的数的个数。

把这些结果统计起来即可。

四.程序代码#include<iostream.h>int s[10]; //记录0~9出现的次数int a[10]; //a[i]记录n位数的规律void sum(int n,int l,int m){ if(m==1){int zero=1;for(int i=0;i<=l;i++) //去除前缀0{ s[0]-=zero;zero*=10;} }if(n<10){for(int i=0;i<=n;i++){ s[i]+=1; }return;}//位数为1位时,出现次数加1//位数大于1时的出现次数for(int t=1;t<=l;t++)//计算规律f(n)=n*10^(n-1){m=1;int i;for(i=1;i<t;i++)m=m*10;a[t]=t*m;}int zero=1;for(int i=0;i<l;i++){ zero*= 10;} //求出输入数为10的n次方int yushu=n%zero; //求出最高位以后的数int zuigao=n/zero; //求出最高位zuigaofor(i=0;i<zuigao;i++){ s[i]+=zero;} //求出0~zuigao-1位的数的出现次数for(i=0;i<10;i++){ s[i]+=zuigao*a[l];} //求出与余数位数相同的0~zuigao-1位中0~9出现的次数//如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数if(yushu==0) //补上所缺的0数,并且最高位加1{ s[zuigao]++;s[0]+=l; }else{ i=0;while((zero/=10)>yushu){ i++; }s[0]+=i*(yushu+1);//补回因作模操作丢失的0s[zuigao]+=(yushu+1);//补回最高位丢失的数目sum(yushu,l-i-1,m+1);//处理余位数}}void main(){ int i,m,n,N,l;cout<<"输入数字要查询的数字:";cin>>N;cout<<'\n';n = N;for(i=0;n>=10;i++){ n/=10; } //求出N的位数n-1l=i;sum(N,l,1);for(i=0; i<10;i++){ cout<< "数字"<<i<<"出现了:"<<s[i]<<"次"<<'\n'; }}五.程序调试中的问题调试过程,页码出现报错。

算法实验报告

算法实验报告

算法实验报告算法实验报告引言:算法是计算机科学的核心内容之一,它是解决问题的方法和步骤的描述。

算法的设计和分析是计算机科学与工程中的重要研究方向之一。

本实验旨在通过对算法的实际应用和实验验证,深入理解算法的性能和效果。

实验一:排序算法的比较在本实验中,我们将比较三种常见的排序算法:冒泡排序、插入排序和快速排序。

我们将通过对不同规模的随机数组进行排序,并记录每种算法所需的时间和比较次数,以评估它们的性能。

实验结果显示,快速排序是最快的排序算法,其时间复杂度为O(nlogn),比较次数也相对较少。

插入排序的时间复杂度为O(n^2),比较次数较多,但对于小规模的数组排序效果较好。

而冒泡排序的时间复杂度也为O(n^2),但比较次数更多,效率相对较低。

实验二:图的最短路径算法在图的最短路径问题中,我们将比较Dijkstra算法和Floyd-Warshall算法的效率和准确性。

我们将使用一个带权有向图,并计算从一个顶点到其他所有顶点的最短路径。

实验结果表明,Dijkstra算法适用于单源最短路径问题,其时间复杂度为O(V^2),其中V为顶点数。

而Floyd-Warshall算法适用于多源最短路径问题,其时间复杂度为O(V^3)。

两种算法在准确性上没有明显差异,但在处理大规模图时,Floyd-Warshall算法的效率较低。

实验三:动态规划算法动态规划是一种通过将问题分解成子问题并记录子问题的解来解决复杂问题的方法。

在本实验中,我们将比较两种动态规划算法:0-1背包问题和最长公共子序列问题。

实验结果显示,0-1背包问题的动态规划算法可以有效地找到最优解,其时间复杂度为O(nW),其中n为物品个数,W为背包容量。

最长公共子序列问题的动态规划算法可以找到两个序列的最长公共子序列,其时间复杂度为O(mn),其中m和n分别为两个序列的长度。

结论:通过本次实验,我们对不同算法的性能和效果有了更深入的了解。

排序算法中,快速排序是最快且效率最高的;在图的最短路径问题中,Dijkstra算法和Floyd-Warshall算法分别适用于不同的场景;动态规划算法可以解决复杂的问题,并找到最优解。

排序实验报告_排序综合实验报告材料

排序实验报告_排序综合实验报告材料

班级
2*10^7
10 电信 1 班
10^8
操作系统
10^5
Microsoft Windows 7 旗舰版 (64 位/Service Pck 1)
正序
xxxxxxxxxxxxx
逆序
编译软件
直接插入
Visul C++ 6.0
(带监视哨〕
emil
C
609803959.
24.874
10^4
100.158
2*10^4
中选出键值最小的记录,与无序区第一个记录 R 交换;新的无序区为 R 到
各种排序试验结果:
R[n],从中再选出键值最小的记录,与无序区第一个记录 R 交换;类似, CPU
第 i 趟排序时 R 到 R[i-1]是有序区,无序区为 R[i]到 R[n],从中选出键
(英特尔)Intel(R) Core(TM) i5 CPU M 480 2.67GHz
〔1〕二路并归排序:开始时,将排序表 R 到 R[n]看成 n 个长度为 1
录,顺序放在已排好序的子序列的后面〔或最前〕,直到全部记录排序完 的有序子表,把这些子表两两并归,便得到 n/2 个有序的子表〔当 n 为奇
毕。
数时,并归后仍是有一个长度为 1 的子表〕;然后,再把这 n/2 个有序的
〔1〕直接选择排序:首先,全部记录组成初始无序区 R 到 R[n],从 子表两两并归,如此反复,直到最终得到一个程度为 n 的有序表为止。
指导老师: 胡圣荣
序与排序要求相反时就交换两者的位置,直到没有反序的记录为止。
日期: 20XX.12.15~20XX.1.5
〔1〕冒泡排序:设想排序表 R 到 R[n]垂直放置,将每个记录 R[i]看

信息算法分析实验报告

信息算法分析实验报告

一、实验目的1. 理解信息算法的基本概念和原理。

2. 掌握信息算法的常见类型及其应用场景。

3. 学习如何分析算法的复杂度,包括时间复杂度和空间复杂度。

4. 通过实际操作,提高运用信息算法解决实际问题的能力。

二、实验内容本次实验主要围绕以下内容展开:1. 排序算法:选择排序、冒泡排序、插入排序、快速排序、归并排序、堆排序等。

2. 查找算法:顺序查找、二分查找、散列表查找等。

3. 动态规划:0-1背包问题、最长公共子序列问题等。

4. 贪心算法:活动选择问题、背包问题等。

三、实验过程1. 选择排序:通过交换元素的位置,将数组排序。

时间复杂度为O(n^2),空间复杂度为O(1)。

```cvoid selectionSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {int min_idx = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[min_idx]) {min_idx = j;}}swap(&arr[min_idx], &arr[i]);}}```2. 快速排序:选取一个基准元素,将数组分为两部分,使得左边的元素都比基准小,右边的元素都比基准大。

时间复杂度为O(nlogn),空间复杂度为O(logn)。

```cint partition(int arr[], int low, int high) {int pivot = arr[high];int i = (low - 1);for (int j = low; j <= high - 1; j++) {if (arr[j] < pivot) {i++;swap(&arr[i], &arr[j]);}}swap(&arr[i + 1], &arr[high]);return (i + 1);}void quickSort(int arr[], int low, int high) {if (low < high) {int pi = partition(arr, low, high);quickSort(arr, low, pi - 1);quickSort(arr, pi + 1, high);}}```3. 动态规划解决0-1背包问题:给定一个背包容量和若干物品,每个物品有一个价值和重量,求解背包中物品的最大价值。

算法分析与设计实验报告合并排序快速排序

算法分析与设计实验报告合并排序快速排序

算法分析与设计实验报告:合并排序与快速排序一、引言算法是计算机科学中非常重要的一部分,它涉及到解决问题的方法和步骤。

合并排序和快速排序是两种经典而常用的排序算法。

本文将对这两种排序算法进行分析和设计实验,通过对比它们的性能和效率,以期得出最优算法。

二、合并排序合并排序是一种分治算法,它将原始数组不断分解为更小的数组,直到最后细分为单个元素。

然后,再将这些单个元素两两合并,形成一个有序数组。

合并排序的核心操作是合并两个有序的数组。

1. 算法步骤(1)将原始数组分解为更小的子数组,直到每个子数组只有一个元素;(2)两两合并相邻的子数组,同时进行排序,生成新的有序数组;(3)重复步骤(2),直到生成最终的有序数组。

2. 算法性能合并排序的最优时间复杂度为O(nlogn),其中n为待排序数组的长度。

无论最好情况还是最坏情况,合并排序的复杂度都相同。

合并排序需要额外的存储空间来存储临时数组,所以空间复杂度为O(n)。

三、快速排序快速排序也是一种分治算法,它将原始数组根据一个主元(pivot)分成两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元。

然后,递归地对这两个子数组进行排序,最后得到有序数组。

快速排序的核心操作是划分。

1. 算法步骤(1)选择一个主元(pivot),可以是随机选择或者固定选择第一个元素;(2)将原始数组根据主元划分为两个子数组,一个子数组的元素都小于主元,另一个子数组的元素都大于主元;(3)递归地对这两个子数组进行快速排序;(4)重复步骤(2)和(3),直到每个子数组只有一个元素,即得到最终的有序数组。

2. 算法性能快速排序的平均时间复杂度为O(nlogn),其中n为待排序数组的长度。

最坏情况下,当每次选择的主元都是最小或最大元素时,时间复杂度为O(n^2)。

快速排序是原地排序,不需要额外的存储空间,所以空间复杂度为O(1)。

四、实验设计为了验证合并排序和快速排序的性能和效率,我们设计以下实验:1. 实验目的:比较合并排序和快速排序的时间复杂度和空间复杂度。

算法与分析实验报告

算法与分析实验报告

算法与分析实验报告一、引言算法是现代计算机科学中的核心概念,通过合理设计的算法可以解决复杂的问题,并提高计算机程序的执行效率。

本次实验旨在通过实际操作和数据统计,对比分析不同算法的执行效率,探究不同算法对于解决特定问题的适用性和优劣之处。

二、实验内容本次实验涉及两个经典的算法问题:排序和搜索。

具体实验内容如下:1. 排序算法- 冒泡排序- 插入排序- 快速排序2. 搜索算法- 顺序搜索- 二分搜索为了对比不同算法的执行效率,我们需要设计合适的测试用例并记录程序执行时间进行比较。

实验中,我们将使用随机生成的整数数组作为排序和搜索的测试数据,并统计执行时间。

三、实验步骤1. 算法实现与优化- 实现冒泡排序、插入排序和快速排序算法,并对算法进行优化,提高执行效率。

- 实现顺序搜索和二分搜索算法。

2. 数据生成- 设计随机整数数组生成函数,生成不同大小的测试数据。

3. 实验设计- 设计实验方案,包括测试数据的规模、重复次数等。

4. 实验执行与数据收集- 使用不同算法对随机整数数组进行排序和搜索操作,记录执行时间。

- 多次重复同样的操作,取平均值以减小误差。

5. 数据分析与结果展示- 将实验收集到的数据进行分析,并展示在数据表格或图表中。

四、实验结果根据实验数据的收集与分析,我们得到以下结果:1. 排序算法的比较- 冒泡排序:平均执行时间较长,不适用于大规模数据排序。

- 插入排序:执行效率一般,在中等规模数据排序中表现良好。

- 快速排序:执行效率最高,适用于大规模数据排序。

2. 搜索算法的比较- 顺序搜索:执行时间与数据规模成线性关系,适用于小规模数据搜索。

- 二分搜索:执行时间与数据规模呈对数关系,适用于大规模有序数据搜索。

实验结果表明,不同算法适用于不同规模和类型的问题。

正确选择和使用算法可以显著提高程序的执行效率和性能。

五、实验总结通过本次实验,我们深入了解了不同算法的原理和特点,并通过实际操作和数据分析对算法进行了比较和评估。

算法设计与分析实验报告

算法设计与分析实验报告

算法设计与分析实验报告实验一全排列、快速排序【实验目的】1. 掌握全排列的递归算法。

2. 了解快速排序的分治算法思想。

【实验原理】一、全排列全排列的生成算法就是对于给定的字符集,用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。

任何n个字符集的排列都可以与1~n的n个数字的排列一一对应,因此在此就以n 个数字的排列为例说明排列的生成法。

n个字符的全体排列之间存在一个确定的线性顺序关系。

所有的排列中除最后一个排列外,都有一个后继;除第一个排列外,都有一个前驱。

每个排列的后继都可以从它的前驱经过最少的变化而得到,全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。

二、快速排序快速排序(Quicksort)是对冒泡排序的一种改进。

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

【实验内容】1.全排列递归算法的实现。

2.快速排序分治算法的实现。

【实验结果】1. 全排列:2. 快速排序:实验二最长公共子序列、活动安排问题【实验目的】1. 了解动态规划算法设计思想,运用动态规划算法实现最长公共子序列问题。

2. 了解贪心算法思想,运用贪心算法设计思想实现活动安排问题。

【实验原理】一、动态规划法解最长公共子序列设序列X=和Y=的一个最长公共子序列Z=,则:i. 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;ii. 若xm≠yn且zk≠xm ,则Z是Xm-1和Y的最长公共子序列;iii. 若xm≠yn且z k≠yn ,则Z是X和Yn-1的最长公共子序列。

其中Xm-1=,Yn-1=,Zk-1=。

最长公共子序列问题具有最优子结构性质。

由最长公共子序列问题的最优子结构性质可知,要找出X=和Y=的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。

算法设计与分析实验报告

算法设计与分析实验报告

实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的1.掌握能用分治法求解的问题应满足的条件;2.加深对分治法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

二、实验内容1、找最大和最小元素输入n 个数,找出最大和最小数的问题。

2、归并分类将一个含有n个元素的集合,按非降的次序分类(排序)。

三、实验要求(1)用分治法求解问题(2)上机实现所设计的算法;四、实验过程设计(算法设计过程)1、找最大和最小元素采用分治法,将数组不断划分,进行递归。

递归结束的条件为划分到最后若为一个元素则max和min都是这个元素,若为两个取大值赋给max,小值给min。

否则就继续进行划分,找到两个子问题的最大和最小值后,比较这两个最大值和最小值找到解。

2、归并分类使用分治的策略来将一个待排序的数组分成两个子数组,然后递归地对子数组进行排序,最后将排序好的子数组合并成一个有序的数组。

在合并过程中,比较两个子数组的首个元素,将较小的元素放入辅助数组,并指针向后移动,直到将所有元素都合并到辅助数组中。

五、源代码1、找最大和最小元素#include<iostream>using namespace std;void MAXMIN(int num[], int left, int right, int& fmax, int& fmin); int main() {int n;int left=0, right;int fmax, fmin;int num[100];cout<<"请输入数字个数:";cin >> n;right = n-1;cout << "输入数字:";for (int i = 0; i < n; i++) {cin >> num[i];}MAXMIN(num, left, right, fmax, fmin);cout << "最大值为:";cout << fmax << endl;cout << "最小值为:";cout << fmin << endl;return 0;}void MAXMIN(int num[], int left, int right, int& fmax, int& fmin) { int mid;int lmax, lmin;int rmax, rmin;if (left == right) {fmax = num[left];fmin = num[left];}else if (right - left == 1) {if (num[right] > num[left]) {fmax = num[right];fmin = num[left];}else {fmax = num[left];fmin = num[right];}}else {mid = left + (right - left) / 2;MAXMIN(num, left, mid, lmax, lmin);MAXMIN(num, mid+1, right, rmax, rmin);fmax = max(lmax, rmax);fmin = min(lmin, rmin);}}2、归并分类#include<iostream>using namespace std;int num[100];int n;void merge(int left, int mid, int right) { int a[100];int i, j,k,m;i = left;j = mid+1;k = left;while (i <= mid && j <= right) {if (num[i] < num[j]) {a[k] = num[i++];}else {a[k] = num[j++];}k++;}if (i <= mid) {for (m = i; m <= mid; m++) {a[k++] = num[i++];}}else {for (m = j; m <= right; m++) {a[k++] = num[j++];}}for (i = left; i <= right; i++) { num[i] = a[i];}}void mergesort(int left, int right) { int mid;if (left < right) {mid = left + (right - left) / 2;mergesort(left, mid);mergesort(mid + 1, right);merge(left, mid, right);}}int main() {int left=0,right;int i;cout << "请输入数字个数:";cin >> n;right = n - 1;cout << "输入数字:";for (i = 0; i < n; i++) {cin >> num[i];}mergesort(left,right);for (i = 0; i < n; i++) {cout<< num[i];}return 0;}六、运行结果和算法复杂度分析1、找最大和最小元素图1-1 找最大和最小元素结果算法复杂度为O(logn)2、归并分类图1-2 归并分类结果算法复杂度为O(nlogn)实验二背包问题和最小生成树算法实现(用贪心法)一、实验目的1.掌握能用贪心法求解的问题应满足的条件;2.加深对贪心法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。

常见算法设计实验报告(3篇)

常见算法设计实验报告(3篇)

第1篇一、实验目的通过本次实验,掌握常见算法的设计原理、实现方法以及性能分析。

通过实际编程,加深对算法的理解,提高编程能力,并学会运用算法解决实际问题。

二、实验内容本次实验选择了以下常见算法进行设计和实现:1. 排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。

2. 查找算法:顺序查找、二分查找。

3. 图算法:深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)。

4. 动态规划算法:0-1背包问题。

三、实验原理1. 排序算法:排序算法的主要目的是将一组数据按照一定的顺序排列。

常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。

2. 查找算法:查找算法用于在数据集中查找特定的元素。

常见的查找算法包括顺序查找和二分查找。

3. 图算法:图算法用于处理图结构的数据。

常见的图算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)等。

4. 动态规划算法:动态规划算法是一种将复杂问题分解为子问题,通过求解子问题来求解原问题的算法。

常见的动态规划算法包括0-1背包问题。

四、实验过程1. 排序算法(1)冒泡排序:通过比较相邻元素,如果顺序错误则交换,重复此过程,直到没有需要交换的元素。

(2)选择排序:每次从剩余元素中选取最小(或最大)的元素,放到已排序序列的末尾。

(3)插入排序:将未排序的数据插入到已排序序列中适当的位置。

(4)快速排序:选择一个枢纽元素,将序列分为两部分,使左侧不大于枢纽,右侧不小于枢纽,然后递归地对两部分进行快速排序。

(5)归并排序:将序列分为两半,分别对两半进行归并排序,然后将排序好的两半合并。

(6)堆排序:将序列构建成最大堆,然后重复取出堆顶元素,并调整剩余元素,使剩余元素仍满足最大堆的性质。

2. 查找算法(1)顺序查找:从序列的第一个元素开始,依次比较,直到找到目标元素或遍历完整个序列。

关于算法的实验报告(3篇)

关于算法的实验报告(3篇)

第1篇一、实验目的1. 理解快速排序算法的基本原理和实现方法。

2. 掌握快速排序算法的时间复杂度和空间复杂度分析。

3. 通过实验验证快速排序算法的效率。

4. 提高编程能力和算法设计能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验原理快速排序算法是一种分而治之的排序算法,其基本思想是:选取一个基准元素,将待排序序列分为两个子序列,其中一个子序列的所有元素均小于基准元素,另一个子序列的所有元素均大于基准元素,然后递归地对这两个子序列进行快速排序。

快速排序算法的时间复杂度主要取决于基准元素的选取和划分过程。

在平均情况下,快速排序的时间复杂度为O(nlogn),但在最坏情况下,时间复杂度会退化到O(n^2)。

四、实验内容1. 快速排序算法的代码实现2. 快速排序算法的时间复杂度分析3. 快速排序算法的效率验证五、实验步骤1. 设计快速排序算法的C++代码实现,包括以下功能:- 选取基准元素- 划分序列- 递归排序2. 编写主函数,用于生成随机数组和测试快速排序算法。

3. 分析快速排序算法的时间复杂度。

4. 对不同规模的数据集进行测试,验证快速排序算法的效率。

六、实验结果与分析1. 快速排序算法的代码实现```cppinclude <iostream>include <vector>include <cstdlib>include <ctime>using namespace std;// 生成随机数组void generateRandomArray(vector<int>& arr, int n) {srand((unsigned)time(0));for (int i = 0; i < n; ++i) {arr.push_back(rand() % 1000);}}// 快速排序void quickSort(vector<int>& arr, int left, int right) { if (left >= right) {return;}int i = left;int j = right;int pivot = arr[(left + right) / 2]; // 选取中间元素作为基准 while (i <= j) {while (arr[i] < pivot) {i++;}while (arr[j] > pivot) {j--;}if (i <= j) {swap(arr[i], arr[j]);i++;j--;}}quickSort(arr, left, j);quickSort(arr, i, right);}int main() {int n = 10000; // 测试数据规模vector<int> arr;generateRandomArray(arr, n);clock_t start = clock();quickSort(arr, 0, n - 1);clock_t end = clock();cout << "排序用时:" << double(end - start) / CLOCKS_PER_SEC << "秒" << endl;return 0;}```2. 快速排序算法的时间复杂度分析根据实验结果,快速排序算法在平均情况下的时间复杂度为O(nlogn),在最坏情况下的时间复杂度为O(n^2)。

排序算法实验报告

排序算法实验报告

数据结构实验报告八种排序算法实验报告一、实验内容编写关于八种排序算法的C语言程序,要求包含直接插入排序、希尔排序、简单项选择择排序、堆排序、冒泡排序、快速排序、归并排序和基数排序。

二、实验步骤各种内部排序算法的比较:1.八种排序算法的复杂度分析〔时间与空间〕。

2.八种排序算法的C语言编程实现。

3.八种排序算法的比较,包括比较次数、移动次数。

三、稳定性,时间复杂度和空间复杂度分析比较时间复杂度函数的情况:时间复杂度函数O(n)的增长情况所以对n较大的排序记录。

一般的选择都是时间复杂度为O(nlog2n)的排序方法。

时间复杂度来说:(1)平方阶(O(n2))排序各类简单排序:直接插入、直接选择和冒泡排序;(2)线性对数阶(O(nlog2n))排序快速排序、堆排序和归并排序;(3)O(n1+§))排序,§是介于0和1之间的常数。

希尔排序(4)线性阶(O(n))排序基数排序,此外还有桶、箱排序。

说明:当原表有序或基本有序时,直接插入排序和冒泡排序将大大减少比较次数和移动记录的次数,时间复杂度可降至O〔n〕;而快速排序则相反,当原表基本有序时,将蜕化为冒泡排序,时间复杂度提高为O〔n2〕;原表是否有序,对简单项选择择排序、堆排序、归并排序和基数排序的时间复杂度影响不大。

稳定性:排序算法的稳定性:假设待排序的序列中,存在多个具有相同关键字的记录,经过排序,这些记录的相对次序保持不变,则称该算法是稳定的;假设经排序后,记录的相对次序发生了改变,则称该算法是不稳定的。

稳定性的好处:排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。

基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。

另外,如果排序算法稳定,可以防止多余的比较;稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序不是稳定的排序算法:选择排序、快速排序、希尔排序、堆排序四、设计细节排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

几种常见算法的介绍及复杂度分析

几种常见算法的介绍及复杂度分析

几种常见算法的介绍及复杂度分析一、排序算法1.冒泡排序:通过反复交换相邻元素实现排序,每次遍历将最大元素放到最后。

时间复杂度为O(n^2)。

2.插入排序:将未排序元素插入已排序序列的适当位置,时间复杂度为O(n^2)。

3.选择排序:每次选择最小的元素放到已排序序列末尾,时间复杂度为O(n^2)。

4. 快速排序:通过递归将数组分段,并以一个基准元素为准将小于它的元素放在左边,大于它的元素放在右边,时间复杂度为O(nlogn)。

5. 归并排序:将数组递归拆分为多个子数组,对子数组进行排序并合并,时间复杂度为O(nlogn)。

二、查找算法1.顺序查找:从头到尾依次比较目标元素与数组中的元素,时间复杂度为O(n)。

2. 二分查找:依据已排序的数组特性,将目标元素与中间位置的元素比较,并根据大小取舍一半的数组进行查找,时间复杂度为O(logn)。

3.哈希查找:通过哈希函数将目标元素映射到数组的索引位置,时间复杂度为O(1),但可能需要额外的空间。

三、图算法1.广度优先(BFS):从起始节点开始,依次访问其邻居节点,再访问邻居的邻居,直到找到目标节点或遍历所有节点。

时间复杂度为O(V+E),V为顶点数量,E为边的数量。

2.深度优先(DFS):从起始节点开始一直遍历到没有未访问的邻居,再回溯到上一个节点继续遍历,直到找到目标节点或遍历所有节点。

时间复杂度为O(V+E),V为顶点数量,E为边的数量。

3. 最短路径算法(如Dijkstra算法):通过计算起始节点到每个节点的最短路径,找到起始节点到目标节点的最短路径。

时间复杂度为O(V^2),V为顶点数量。

4. 最小生成树算法(如Prim算法):通过贪心策略找到连通图的最小权重生成树,时间复杂度为O(V^2),V为顶点数量。

四、动态规划算法1.背包问题:将问题拆解为若干子问题,并通过求解子问题的最优解推导出原问题的最优解。

时间复杂度为O(nW),n为物品数量,W为背包容量。

实现排序算法的实验报告

实现排序算法的实验报告

一、实验目的1. 理解排序算法的基本原理和特点。

2. 掌握几种常用的排序算法(冒泡排序、选择排序、插入排序、快速排序、归并排序等)的实现方法。

3. 分析不同排序算法的时间复杂度和空间复杂度。

4. 通过实际编程实现排序算法,提高编程能力。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3.83. 开发工具:PyCharm三、实验内容1. 冒泡排序2. 选择排序3. 插入排序4. 快速排序5. 归并排序四、实验步骤1. 冒泡排序(1)编写冒泡排序函数:def bubble_sort(arr)。

(2)输入测试数据:arr = [5, 3, 8, 4, 1]。

(3)调用冒泡排序函数:bubble_sort(arr)。

(4)输出排序后的结果:print(arr)。

2. 选择排序(1)编写选择排序函数:def selection_sort(arr)。

(2)输入测试数据:arr = [5, 3, 8, 4, 1]。

(3)调用选择排序函数:selection_sort(arr)。

(4)输出排序后的结果:print(arr)。

3. 插入排序(1)编写插入排序函数:def insertion_sort(arr)。

(2)输入测试数据:arr = [5, 3, 8, 4, 1]。

(3)调用插入排序函数:insertion_sort(arr)。

(4)输出排序后的结果:print(arr)。

4. 快速排序(1)编写快速排序函数:def quick_sort(arr)。

(2)输入测试数据:arr = [5, 3, 8, 4, 1]。

(3)调用快速排序函数:quick_sort(arr)。

(4)输出排序后的结果:print(arr)。

5. 归并排序(1)编写归并排序函数:def merge_sort(arr)。

(2)输入测试数据:arr = [5, 3, 8, 4, 1]。

(3)调用归并排序函数:merge_sort(arr)。

数组各种排序算法和复杂度分析

数组各种排序算法和复杂度分析

数组各种排序算法和复杂度分析Java排序算法1)分类:插⼊排序(直接插⼊排序、希尔排序)交换排序(冒泡排序、快速排序)选择排序(直接选择排序、堆排序)归并排序分配排序(箱排序、基数排序)所需辅助空间最多:归并排序所需辅助空间最少:堆排序平均速度最快:快速排序不稳定:快速排序,希尔排序,堆排序。

2)选择排序算法的时候要考虑数据的规模、数据的类型、数据已有的顺序。

⼀般来说,当数据规模较⼩时,应选择直接插⼊排序或冒泡排序。

任何排序算法在数据量⼩时基本体现不出来差距。

考虑数据的类型,⽐如如果全部是正整数,那么考虑使⽤桶排序为最优。

考虑数据已有顺序,快排是⼀种不稳定的排序(当然可以改进),对于⼤部分排好的数据,快排会浪费⼤量不必要的步骤。

数据量极⼩,⽽起已经基本排好序,冒泡是最佳选择。

我们说快排好,是指⼤量随机数据下,快排效果最理想。

⽽不是所有情况。

3)总结:——按平均的时间性能来分:时间复杂度为O(nlogn)的⽅法有:快速排序、堆排序和归并排序,其中以快速排序为最好;时间复杂度为O(n2)的有:直接插⼊排序、起泡排序和简单选择排序,其中以直接插⼊为最好,特别是对那些对关键字近似有序的记录序列尤为如此;时间复杂度为O(n)的排序⽅法只有,基数排序。

当待排记录序列按关键字顺序有序时,直接插⼊排序和起泡排序能达到O(n)的时间复杂度;⽽对于快速排序⽽⾔,这是最不好的情况,此时的时间性能蜕化为O(n2),因此是应该尽量避免的情况。

简单选择排序、堆排序和归并排序的时间性能不随记录序列中关键字的分布⽽改变。

——按平均的空间性能来分(指的是排序过程中所需的辅助空间⼤⼩):所有的简单排序⽅法(包括:直接插⼊、起泡和简单选择)和堆排序的空间复杂度为O(1);快速排序为O(logn ),为栈所需的辅助空间;归并排序所需辅助空间最多,其空间复杂度为O(n );链式基数排序需附设队列⾸尾指针,则空间复杂度为O(rd )。

——排序⽅法的稳定性能:稳定的排序⽅法指的是,对于两个关键字相等的记录,它们在序列中的相对位置,在排序之前和经过排序之后,没有改变。

算法分析与复杂性理论 实验报告 凸包问题

算法分析与复杂性理论 实验报告 凸包问题

实验过程及内容: (实验代码已作为附件提交,名为“算法实验三.cpp” ) 凸包问题的描述与定义: 凸包的定义为: 平面的一个子集 S 被称为是“凸”的, 当且进当对于任意两点 p,q∈S, 线段都完全属于 S。几何 S 的凸包 CH(S),就是包含 S 的最小凸集,更准确地说,它是 包含 S 的所有凸集的交。由此还可以推出凸包的很多性质,包括一条直线如果与凸包相 交(不是相切)的话,最多交于两条边或者两个面。 一组平面上的点,求一个包含所有点的最小凸边形,既是凸包问题。 形象地说:在一平木板(平面)上钉若干钉子(点) ,将一橡皮筋套上去后,会把 钉子圈起来,形成一个凸边形,即为该点集的凸包。
指导教师批阅意见:
成绩评定:
指导教师签字: 年 月 日
备注:
注:1、报告内的项目或内容设置,可根据实际情况加以调整和补充。 2、教师批改学生实验报告时间应在学生提交实验报告时间后 10 日内。
深 圳 大 学 实 验 报 告
课程名称:
算法分析与复杂性理论
实验项目名称:
实验三 分治法求凸包问题
学院:
计算机与软件学院
专业:
软件工程
指导教师:
杨烜
报告人:文成 学号:2150230509 班级: 15 级软工学术型
实验时间:
2015-10-22
实验报告提交时间:
2015-10-24
教务部制
实验目的与要求: 实验目的: (1) (2) 掌握分治法思想。 学会凸包问题求解方法。
由此就可得到凸包问题的分治算法。
Step1:把 S 中的点按 x 坐标进行排序。 Step2:划分成两个子集 S1,S2. Step3:P1=CH(S1)和 P2=CH(S2). Step:合并 P1,P2 得到解集 P.

基础算法实验报告总结

基础算法实验报告总结

一、实验背景与目的随着计算机科学的发展,算法作为其核心内容之一,日益受到重视。

为了提高对基础算法的理解和掌握,本实验通过对几种常见基础算法的学习和实践,旨在加深对算法原理的理解,提高算法设计能力。

二、实验内容与过程本次实验主要涉及以下几种基础算法:1. 快速排序算法快速排序是一种常用的排序算法,其基本思想是分治法。

通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

实验过程中,我们实现了快速排序算法,并针对不同规模的数据进行了测试,验证了算法的效率和稳定性。

2. 二分查找算法二分查找算法是一种在有序数组中查找特定元素的算法。

其基本思想是将待查找的元素与数组的中间元素进行比较,根据比较结果,将查找范围缩小一半,直至找到目标元素或查找范围为空。

实验中,我们实现了二分查找算法,并通过实例演示了其在不同情况下的查找过程,验证了算法的正确性和效率。

3. 动态规划算法动态规划是一种通过将问题分解为子问题,并存储子问题的解以避免重复计算的方法。

实验中,我们以斐波那契数列为例,实现了动态规划算法,并分析了其时间复杂度和空间复杂度。

4. 回溯法回溯法是一种通过尝试所有可能的解,并逐步排除不满足条件的解,从而找到问题解的方法。

实验中,我们以八皇后问题为例,实现了回溯法,并分析了算法的搜索过程和效率。

三、实验结果与分析1. 快速排序算法实验结果表明,快速排序算法在处理大规模数据时,具有较好的效率。

其平均时间复杂度为O(nlogn),在最坏情况下为O(n^2)。

通过优化选择基准元素的方法,可以提高算法的稳定性。

2. 二分查找算法二分查找算法在有序数组中具有很高的效率,平均时间复杂度为O(logn)。

在处理大规模数据时,二分查找算法的性能明显优于顺序查找算法。

3. 动态规划算法动态规划算法在解决某些问题时具有明显的优势,尤其是在具有重叠子问题的情况下。

霍夫曼算法实验报告

霍夫曼算法实验报告

一、实验目的1. 理解霍夫曼算法的基本原理和过程。

2. 掌握霍夫曼算法的编程实现。

3. 分析霍夫曼算法的复杂度和性能。

二、实验原理霍夫曼算法是一种贪心算法,用于数据压缩。

其基本思想是根据字符出现的频率,构造出一棵最优二叉树,从而得到最优的编码方案。

霍夫曼算法的步骤如下:1. 统计每个字符的出现频率。

2. 将频率相同的字符视为一类,按照频率从小到大排序。

3. 将排序后的字符中频率最小的两个字符合并成一个新字符,新字符的频率为两个字符频率之和。

4. 将新字符插入到排序后的字符中,并重新排序。

5. 重复步骤3和4,直到只剩下一个字符为止。

6. 根据合并的顺序,从根节点到叶子节点的路径上,将0和1分别赋给路径,形成每个字符的霍夫曼编码。

三、实验内容1. 编写程序实现霍夫曼算法。

2. 对给定的字符集进行编码和解码。

3. 分析霍夫曼算法的复杂度和性能。

四、实验步骤1. 编写程序,统计字符集的频率。

2. 根据频率构造最优二叉树。

3. 根据最优二叉树生成霍夫曼编码。

4. 编写解码程序,根据霍夫曼编码解码字符。

5. 测试程序,分析霍夫曼算法的复杂度和性能。

五、实验结果与分析1. 实验结果(1)霍夫曼编码示例假设字符集为:{a, b, c, d, e, f},频率分别为:{4, 2, 3, 5, 7, 8}。

(2)霍夫曼编码根据霍夫曼算法,得到以下编码:a: 0b: 10c: 110d: 1110e: 1111f: 100(3)解码根据霍夫曼编码,解码结果为:{a, b, c, d, e, f}。

2. 实验分析(1)复杂度分析霍夫曼算法的时间复杂度为O(nlogn),其中n为字符集的长度。

这是因为算法需要构建一个最优二叉树,而构建最优二叉树的时间复杂度为O(nlogn)。

(2)性能分析霍夫曼编码具有较好的压缩效果,其平均编码长度较其他编码方法短。

当字符集中字符的频率差异较大时,霍夫曼编码的压缩效果更明显。

六、实验总结通过本次实验,我们掌握了霍夫曼算法的基本原理和编程实现,分析了算法的复杂度和性能。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

深圳大学实验报告课程名称:算法设计与分析实验名称:多种排序算法的算法实现及性能比较学院:计算机与软件学院专业:计算机科学与技术报告人:张健哲学号:2013150372 班级: 3 同组人:无指导教师:李炎然实验时间:2015/3/25——2015/4/8实验报告提交时间:2015/4/8教务处制一.实验目的1.掌握选择排序、冒泡排序、合并排序、快速排序、插入排序算法原理2.掌握不同排序算法时间效率的经验分析方法,验证理论分析与经验分析的一致性。

二.实验步骤与结果实验总体思路:利用switch结构来选择实验所要用的排序算法,每一种排序都用相同的计算运行时间的代码,不同的算法就在算法实现部分进行改动(如下代码1至5所示)。

不断的改变数据规模,每一个规模在实验时,用循环进行多次实验并作为样本记录消耗的时间。

最后输出在不同排序算法下,不同的数据规模的20次实验样本和平均用时(如下图1至5所示)。

各排序算法的实现及实验结果:(注1:以下代码全部为伪代码,具体代码实现请参照程序中的代码)(注2:图中显示的时间单位均为毫秒,图中“排序所花时间”一项为平均消耗时间,平均消耗时间结果以20组样本计算平均值后取整得到(并非四舍五入)。

)1、选择排序代码1:for i=0 to n-2min=ifor j= i+1 to n-1if ele[min]>ele[j] min=jswap(ele[i],ele[min]) //交换图1、选择排序在不同数据规模下排序所消耗的时间2、冒泡排序代码2:for i= 0 to n-1for j=0 to n-1-iif a[j]>a[j+1]swap(a[j],a[j+1]) //交换图2、冒泡排序在不同数据规模下排序所消耗的时间3、合并排序代码3:Merge(ele[1...n],left,right)middle=(left+right)/2if right>1eft+1Merge(ele,left,middle)Merge(ele,middle+1,right)l←left r←right i←leftwhile l<=middle&&r<=right //两组分别一一比较,数据小的放入ele if ele[l]<=ele[r]t[i++]←ele[l++]elset[i++]←ele[r++]while l>middle&&r<=r //只剩一组还有剩余的时,将剩下的按顺序放入ele[i++]=s[r++]while l<=middle && r>rightele[i++]=s[l++];图3、合并排序在不同数据规模下排序所消耗的时间4、快速排序代码4:quick(ele[0...n-1],left,right)if l<rl←left r←right x←ele[l];while l<rwhile l<r && x<=ele[r] //找到一个比x小的数之后交换到前面的部分r--if l<rele[l]←ele[r] l++while l<r && x>ele[l] //与上面相反ll++if l<rele[r]←ele[l] r--ele[l]←x;quick(ele,left,l-1) // 递归调用quick(ele,l+1,right)图4、快速排序在不同数据规模下排序所消耗的时间5、插入排序代码5:for i=1→n-1if ele[i]<ele[i-1] temp=ele[i]for j= i-1 to 0 && ele[j]>tempele[j+1]←ele[j]ele[j+1]←temp图5、插入排序在不同数据规模下排序所消耗的时间三.实验分析选择排序:图6、由图1数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表1、图7所示):(由于图片占空间大且表达不直白,我将所得数据做成表格分析,下同)表1、选择排序在不同数据规模下排序所消耗的时间图7、由表1数据整合而成的折线图图形上:形状基本符合n2(二次增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000: 158*22=632≈634 10000→30000:158*32=1422≈142420000→40000: 634*22=2536≈2541其他倍数也可得到类似的结果。

结论:我们发现,由于时间复杂度是o(n2)并且该排序的主要操作是比较操作,当数据规模扩大n倍时,相应的在时间的消耗上会扩大n2倍,同时我们发现,理论上乘以n2后的数据普遍会略小于实际数据,这主要原因可能是除了比较操作之外,赋值操作也随着n的增加逐渐增大,并且会在时间上体现出来,此外轻微的误差可能是数据的差异造成或者电脑等其他因素造成。

冒泡排序:图8、由图2数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表2、图9所示):表2、冒泡排序在不同数据规模下排序所消耗的时间图9、由表2数据整合而成的折线图图形上:形状基本符合n2(二次增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000:284*22=1136≠1266(误差130) 10000→30000:284*32=2556≠2899(误差343)20000→40000:1266*22=5064≠5313(误差149)其他倍数也可得到类似的结果。

结论:我们发现,虽然时间复杂度是o(n2),但当数据规模扩大n倍时,并没有相应的在时间的消耗上扩大n2倍,而是多于n2,同时我们发现,这个误差会随着数据规模的扩大而扩大,这主要原因是除了比较操作之外,赋值操作也随着n的增加逐渐增大,而且事实证明在数据比较极端的情况下,赋值操作已经不能忽略不计(这里的赋值操作发生在数据交换时所需要的操作),最糟糕的情况是每次比较就要进行三次的赋值操作,与此相比,电脑等其他因素造成轻微的误差可以忽略不计。

合并排序:图10、由图3数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表3、图11所示):表3、合并排序在不同数据规模下排序所消耗的时间图11、由表3数据整合而成的折线图图形上:形状基本符合n(线性增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000: 24*2log22=48≈51 10000→30000:24*3log23=72≈76 20000→40000: 51*2log222=102≈105其他倍数也可得到类似的结果。

结论:我们发现,由于时间复杂度是o(nlog2n),当数据规模扩大n倍时,相应的在时间的消耗上会扩大nlog2n倍,同时我们发现,理论上乘以nlog2n后的数据普遍会略小于实际数据,这主要原因快速排序需要递归调用,递归调用需要花费额外的时间,此外轻微的误差可能是数据的差异造成或者电脑等其他因素造成。

快速排序:图12、由图4数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表4、图13所示):图13、由表4数据整合而成的折线图图形上:形状基本符合n(线性增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000: 17*2log22=34≈36 10000→30000:17*3log23≈5620000→40000: 26*2log22=54≈56其他倍数也可得到类似的结果。

结论:我们发现,由于时间复杂度是o(nlog2n),当数据规模扩大n倍时,相应的在时间的消耗上会扩大nlog2n倍,同时我们发现,理论上乘以nlog2n后的数据普遍会略小于实际数据,这主要原因快速排序需要递归调用,递归调用需要花费额外的时间,此外轻微的误差可能是数据的差异造成或者电脑等其他因素造成。

插入排序:图14、由图5数据整合而成的折线图为了更清晰的看到排序的数据规模与排序所需时间之间的影响,我将实验的数据规模进行了一些调整,得到的平均数据依旧是以20组数据样本取平均数算得(如下表5、图15所示):表5、插入排序在不同数据规模下排序所消耗的时间图15、由表5数据整合而成的折线图图形上:形状基本符合n2(二次增长)数据上:我们发现当数据规模增大两倍时:当数据规模增大两倍时:10000→20000: 80*22=320≈319 10000→30000:80*32=720≈72320000→40000: 319*22=1276≈1283其他倍数也可得到类似的结果。

结论:我们发现,由于时间复杂度是o(n2),当数据规模扩大n倍时,相应的在时间的消耗上会扩大n2倍,理论上,如果数据太具有特殊性,那此算法被影响的程度会比较大,他的的比较次数可以从线性次数,到n2次,赋值次数也可能由常数次变成n2总的来说,受数据影响较大,由于我实验基数少,所以无法得出此结论。

将五种排序的实验汇总在一起,如下图16所示图16、由图6、8、10、12、14整合而来从图中以及之前的分析中我们可以得到以下结论时间复杂度同样为o(n2)的选择、冒泡和合并排序,在数据处理上相差的也比较大,其中1、冒泡排序平均耗时最多,其主要原因是:冒泡排序在比较次数上达到了o(n2),但这种排序同时也受交换次数的影响,而且最多时间复杂度也是o(n2)。

如此,同样是o(n2),但冒泡排序的二次项系数会比另外两个大不少,所以最为耗时。

2、选择排序和插入排序相比较,插入排序更快,其原因是:选择排序需要从序列中找到当前最大或最小的值才能进行排序,因此每次都需要与子序列中的全部元素进行比较。

而插入排序无需比较子序列全部元素,只需要找到当前序列第一个比自己大或小的元素,将自身插入到其前一个位置即可。

3、同样是o(nlog2n)但快速排序更快:快速排序出现最差的情况并不是由于输入数据,而是选取到的随机数本身,选到极端的情况非常小,所以对于绝大部分数据而言都是能达o (nlog2n),而合并排序需要赋值的语句还是较多,受输入数据的影响比快排大,所以当数据规模较大时,不受输入数据影响的快速排序更快四.实验心得本次实验虽然花费很大的心思,但确实让我对这几种排序的认识更加深刻,同样的数据,排序的时间可以相差如此之大,这可能会改变我每次都使用冒泡排序的这一习惯,同时,对算法的优良性不同而导致的结果差异之大,感觉到好的算法是多么的重要,当然合理利用算法也是不可忽视的。

相关文档
最新文档