排序实验报告

合集下载

数据结构实验报告八-快速排序

数据结构实验报告八-快速排序

实验8 快速排序1.需求分析(1)输入的形式和输入值的范围:第一行是一个整数n,代表任务的件数。

接下来一行,有n个正整数,代表每件任务所用的时间。

中间用空格或者回车隔开。

不对非法输入做处理,及假设用户输入都是合法的。

(2)输出的形式:输出有n行,每行一个正整数,从第一行到最后一行依次代表着操作系统要处理的任务所用的时间。

按此顺序进行,则使得所有任务等待时间最小。

(3)程序所能达到的功能:在操作系统中,当有n 件任务同时来临时,每件任务需要用时ni,输出所有任务等待的时间和最小的任务处理顺序。

(4)测试数据:输入请输入任务个数:9请输入任务用时:5 3 4 2 6 1 5 7 3输出任务执行的顺序:1 2 3 3 4 5 5 6 72.概要设计(1)抽象数据类型的定义:为实现上述程序的功能,应以整数存储用户的第一个输入。

并将随后输入的一组数据储存在整数数组中。

(2)算法的基本思想:如果将任务按完成时间从小到大排序,则在完成前一项任务时后面任务等待的时间总和最小,即得到最小的任务处理顺序。

采取对输入的任务时间进行快速排序的方法可以在相对较小的时间复杂度下得到从小到大的顺序序列。

3.详细设计(1)实现概要设计中定义的所有数据类型:第一次输入的正整数要求大于零,为了能够存储,采用int型定义变量。

接下来输入的一组整数,数据范围大于零,为了排序需要,采用线性结构存储,即int类型的数组。

(2)实现程序的具体步骤:一.程序主要采取快速排序的方法处理无序数列:1.在序列中根据随机数确定轴值,根据轴值将序列划分为比轴值小和比轴值大的两个子序列。

2.对每个子序列采取从左右两边向中间搜索的方式,不断将值与轴值比较,如果左边的值大于轴值而右边的小于轴值则将二者交换,直到左右交叉。

3.分别对处理完毕的两个子序列递归地采取1,2步的操作,直到子序列中只有一个元素。

二.程序各模块的伪代码:1、主函数int main(){int n;cout<<"请输入任务个数:";cin>>n;int a[n];cout<<"请输入任务用时:";for(int i=0;i<n;i++) cin>>a[i];qsort(a,0,n-1); //调用“快排函数”cout<<"任务执行的顺序:";for(int i=0;i<n;i++) cout<<a[i]<<" "; //输出排序结果}2、快速排序算法:void qsort(int a[],int i,int j){if(j<=i)return; //只有一个元素int pivotindex=findpivot(a,i,j); //调用“轴值寻找函数”确定轴值swap(a,pivotindex,j); //调用“交换函数”将轴值置末int k=partition(a,i-1,j,a[j]); //调用“分割函数”根据轴值分割序列swap(a,k,j);qsort(a,i,k-1); //递归调用,实现子序列的调序qsort(a,k+1,j);}3、轴值寻找算法://为了保证轴值的“随机性”,采用时间初始化种子。

利用指针排序实验报告(3篇)

利用指针排序实验报告(3篇)

第1篇一、实验目的1. 理解指针在排序算法中的应用。

2. 掌握几种常见的排序算法(如冒泡排序、选择排序、插入排序等)的指针实现方式。

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

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验内容本次实验主要实现了以下排序算法:1. 冒泡排序2. 选择排序3. 插入排序以下是对每种排序算法的具体实现和性能分析。

1. 冒泡排序(1)算法原理冒泡排序是一种简单的排序算法。

它重复地遍历待排序的序列,比较每对相邻的元素,如果它们的顺序错误就把它们交换过来。

遍历序列的工作是重复地进行,直到没有再需要交换的元素为止。

(2)指针实现```cppvoid bubbleSort(int arr, int len) {for (int i = 0; i < len - 1; i++) {for (int j = 0; j < len - 1 - i; j++) {if ((arr + j) > (arr + j + 1)) {int temp = (arr + j);(arr + j) = (arr + j + 1);(arr + j + 1) = temp;}}}}```(3)性能分析冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1)。

当待排序序列基本有序时,冒泡排序的性能较好。

2. 选择排序(1)算法原理选择排序是一种简单直观的排序算法。

它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

以此类推,直到所有元素均排序完毕。

(2)指针实现```cppvoid selectionSort(int arr, int len) {for (int i = 0; i < len - 1; i++) {int minIndex = i;for (int j = i + 1; j < len; j++) {if ((arr + j) < (arr + minIndex)) {minIndex = j;}}int temp = (arr + i);(arr + i) = (arr + minIndex);(arr + minIndex) = temp;}}```(3)性能分析选择排序的时间复杂度为O(n^2),空间复杂度为O(1)。

排序检验实验报告

排序检验实验报告

一、实验目的1. 理解排序检验的基本原理和方法。

2. 掌握排序检验的应用场景。

3. 通过实际操作,验证排序检验的有效性。

二、实验原理排序检验(Rank Test)是一种非参数检验方法,用于检验两个独立样本是否来自同一总体。

其基本思想是将样本数据从小到大排序,计算两个样本的秩和,然后根据秩和比较两个样本是否具有显著差异。

三、实验材料1. 计算机2. 数据处理软件(如SPSS、R等)3. 实验数据四、实验步骤1. 收集实验数据,确保两组数据相互独立。

2. 对两组数据进行排序,得到各自的秩。

3. 计算两组数据的秩和。

4. 根据秩和计算检验统计量。

5. 根据检验统计量查表得到临界值。

6. 判断两组数据是否来自同一总体。

五、实验结果与分析1. 数据描述本实验选取了两组独立样本,分别为样本A和样本B。

样本A包含10个数据,样本B包含10个数据。

两组数据如下:样本A:3, 5, 7, 8, 9, 10, 12, 13, 14, 15样本B:1, 4, 6, 7, 8, 9, 10, 11, 12, 132. 排序及秩计算将两组数据从小到大排序,得到各自的秩:样本A:1, 2, 3, 4, 5, 6, 7, 8, 9, 10样本B:1, 2, 3, 4, 5, 6, 7, 8, 9, 103. 秩和计算计算两组数据的秩和:样本A秩和:1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55样本B秩和:1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 554. 检验统计量及临界值计算检验统计量:T = |秩和A - 秩和B| / √[nA nB (nA + nB + 1) / 12]T = |55 - 55| / √[10 10 (10 + 10 + 1) / 12]T = 0查表得到临界值,以α = 0.05为例,查表得到临界值为1.98。

5. 判断结果由于计算得到的检验统计量T = 0小于临界值1.98,因此无法拒绝原假设,即两组数据来自同一总体。

数据结构实验报告-排序

数据结构实验报告-排序

数据结构实验报告-排序一、实验目的本实验旨在探究不同的排序算法在处理大数据量时的效率和性能表现,并对比它们的优缺点。

二、实验内容本次实验共选择了三种常见的排序算法:冒泡排序、快速排序和归并排序。

三个算法将在同一组随机生成的数据集上进行排序,并记录其性能指标,包括排序时间和所占用的内存空间。

三、实验步骤1. 数据的生成在实验开始前,首先生成一组随机数据作为排序的输入。

定义一个具有大数据量的数组,并随机生成一组在指定范围内的整数,用于后续排序算法的比较。

2. 冒泡排序冒泡排序是一种简单直观的排序算法。

其基本思想是从待排序的数据序列中逐个比较相邻元素的大小,并依次交换,从而将最大(或最小)的元素冒泡到序列的末尾。

重复该过程直到所有数据排序完成。

3. 快速排序快速排序是一种分治策略的排序算法,效率较高。

它将待排序的序列划分成两个子序列,其中一个子序列的所有元素都小于等于另一个子序列的所有元素。

然后对两个子序列分别递归地进行快速排序。

4. 归并排序归并排序是一种稳定的排序算法,使用分治策略将序列拆分成较小的子序列,然后递归地对子序列进行排序,最后再将子序列合并成有序的输出序列。

归并排序相对于其他算法的优势在于其稳定性和对大数据量的高效处理。

四、实验结果经过多次实验,我们得到了以下结果:1. 冒泡排序在数据量较小时,冒泡排序表现良好,但随着数据规模的增大,其性能明显下降。

排序时间随数据量的增长呈平方级别增加。

2. 快速排序相比冒泡排序,快速排序在大数据量下的表现更佳。

它的排序时间线性增长,且具有较低的内存占用。

3. 归并排序归并排序在各种数据规模下都有较好的表现。

它的排序时间与数据量呈对数级别增长,且对内存的使用相对较高。

五、实验分析根据实验结果,我们可以得出以下结论:1. 冒泡排序适用于数据较小的排序任务,但面对大数据量时表现较差,不推荐用于处理大规模数据。

2. 快速排序是一种高效的排序算法,适用于各种数据规模。

实验报告_冒泡排序法(3篇)

实验报告_冒泡排序法(3篇)

第1篇一、实验目的1. 理解冒泡排序算法的基本原理和操作步骤。

2. 掌握冒泡排序算法的实现方法。

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

4. 通过实验验证冒泡排序算法的效率。

二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发环境:Visual Studio 2019三、实验原理冒泡排序是一种简单的排序算法,其基本思想是通过多次比较和交换相邻元素,将待排序的序列变为有序序列。

冒泡排序算法的基本步骤如下:1. 从第一个元素开始,相邻的两个元素进行比较,如果它们的顺序错误(即第一个元素大于第二个元素),则交换它们的位置。

2. 重复步骤1,对相邻的元素进行比较和交换,直到整个序列的最后一个元素。

3. 第一轮排序完成后,最大的元素被放置在序列的最后一个位置。

4. 从第一个元素开始,对剩余的元素重复步骤1和步骤2,直到序列的倒数第二个元素。

5. 重复步骤3和步骤4,直到整个序列有序。

四、实验步骤1. 编写冒泡排序算法的C++代码,实现上述算法步骤。

2. 在主函数中创建一个待排序的数组。

3. 调用冒泡排序函数对数组进行排序。

4. 输出排序前后的数组,验证排序结果。

五、实验代码```cppinclude <iostream>using namespace std;// 冒泡排序函数void bubbleSort(int arr[], int n) {for (int i = 0; i < n - 1; i++) {for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) {// 交换相邻元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}// 打印数组函数void printArray(int arr[], int n) {for (int i = 0; i < n; i++) {cout << arr[i] << " ";}cout << endl;}int main() {// 创建待排序的数组int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr) / sizeof(arr[0]);// 打印排序前的数组cout << "排序前的数组:\n";printArray(arr, n);// 调用冒泡排序函数bubbleSort(arr, n);// 打印排序后的数组cout << "排序后的数组:\n";printArray(arr, n);return 0;}```六、实验结果与分析1. 运行实验程序,输出排序前后的数组,验证排序结果是否正确。

微机排序实验实验报告

微机排序实验实验报告

一、实验目的1. 熟悉排序算法的基本原理和实现方法。

2. 掌握各种排序算法的性能特点。

3. 通过编程实现常见的排序算法,并进行性能测试和分析。

二、实验内容1. 实现以下排序算法:(1)冒泡排序(2)选择排序(3)插入排序(4)快速排序(5)归并排序2. 对生成的随机数据进行排序,并统计每种排序算法的运行时间。

3. 分析并比较各种排序算法的性能。

三、实验步骤1. 编写排序算法的代码。

(1)冒泡排序:通过比较相邻元素的大小,如果顺序错误则交换,重复这个过程,直到没有需要交换的元素。

(2)选择排序:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

以此类推,直到所有元素均排序完毕。

(3)插入排序:将未排序的数据元素插入到已排序的有序序列中,从而得到一个新的、有序的序列。

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

(5)归并排序:将两个或两个以上的有序表合并成一个新的有序表。

2. 生成随机数据,并进行排序。

3. 使用计时器统计每种排序算法的运行时间。

4. 分析并比较各种排序算法的性能。

四、实验结果与分析1. 实验数据生成1000个随机数,范围在1到10000之间。

2. 实验结果(1)冒泡排序:运行时间约为0.002秒。

(2)选择排序:运行时间约为0.003秒。

(3)插入排序:运行时间约为0.004秒。

(4)快速排序:运行时间约为0.0005秒。

(5)归并排序:运行时间约为0.001秒。

3. 性能分析(1)冒泡排序、选择排序和插入排序属于O(n^2)复杂度的排序算法,其运行时间随着数据量的增加而迅速增加。

(2)快速排序和归并排序属于O(nlogn)复杂度的排序算法,其运行时间随着数据量的增加而逐渐增加,但增长速度较慢。

排序基本算法实验报告

排序基本算法实验报告

一、实验目的1. 掌握排序算法的基本原理和实现方法。

2. 熟悉常用排序算法的时间复杂度和空间复杂度。

3. 能够根据实际问题选择合适的排序算法。

4. 提高编程能力和问题解决能力。

二、实验内容1. 实现并比较以下排序算法:冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序。

2. 对不同数据规模和不同数据分布的序列进行排序,分析排序算法的性能。

3. 使用C++编程语言实现排序算法。

三、实验步骤1. 冒泡排序:将相邻元素进行比较,如果顺序错误则交换,直到序列有序。

2. 插入排序:将未排序的元素插入到已排序的序列中,直到序列有序。

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

4. 快速排序:选择一个枢纽元素,将序列分为两部分,一部分比枢纽小,另一部分比枢纽大,递归地对两部分进行排序。

5. 归并排序:将序列分为两半,分别对两半进行排序,然后将两半合并为一个有序序列。

6. 堆排序:将序列构建成一个最大堆,然后依次取出堆顶元素,最后序列有序。

四、实验结果与分析1. 冒泡排序、插入排序和选择排序的时间复杂度均为O(n^2),空间复杂度为O(1)。

这些算法适用于小规模数据或基本有序的数据。

2. 快速排序的时间复杂度平均为O(nlogn),最坏情况下为O(n^2),空间复杂度为O(logn)。

快速排序适用于大规模数据。

3. 归并排序的时间复杂度和空间复杂度均为O(nlogn),适用于大规模数据。

4. 堆排序的时间复杂度和空间复杂度均为O(nlogn),适用于大规模数据。

五、实验结论1. 根据不同数据规模和不同数据分布,选择合适的排序算法。

2. 冒泡排序、插入排序和选择排序适用于小规模数据或基本有序的数据。

3. 快速排序、归并排序和堆排序适用于大规模数据。

4. 通过实验,加深了对排序算法的理解,提高了编程能力和问题解决能力。

六、实验总结本次实验通过对排序算法的学习和实现,掌握了常用排序算法的基本原理和实现方法,分析了各种排序算法的性能,提高了编程能力和问题解决能力。

排序的实验报告

排序的实验报告

排序的实验报告排序的实验报告引言:排序是计算机科学中非常重要的一个概念,它涉及到对一组数据按照一定规则进行重新排列的操作。

在计算机算法中,排序算法的效率直接影响到程序的运行速度和资源利用率。

为了深入了解各种排序算法的原理和性能,我们进行了一系列的排序实验。

实验一:冒泡排序冒泡排序是最简单的排序算法之一。

它的原理是通过相邻元素的比较和交换来实现排序。

我们编写了一个冒泡排序的算法,并使用Python语言进行实现。

实验中,我们分别对10、100、1000个随机生成的整数进行排序,并记录了排序所需的时间。

实验结果显示,随着数据规模的增加,冒泡排序的时间复杂度呈现出明显的增长趋势。

当数据规模为10时,排序所需的时间约为0.001秒;而当数据规模增加到1000时,排序所需的时间则增加到了1.5秒左右。

这说明冒泡排序的效率较低,对大规模数据的排序并不适用。

实验二:快速排序快速排序是一种常用的排序算法,它的核心思想是通过分治的策略将数据分成较小的子集,然后递归地对子集进行排序。

我们同样使用Python语言实现了快速排序算法,并对相同规模的数据进行了排序实验。

实验结果显示,快速排序的时间复杂度相对较低。

当数据规模为10时,排序所需的时间约为0.0005秒;而当数据规模增加到1000时,排序所需的时间仅为0.02秒左右。

这说明快速排序适用于大规模数据的排序,其效率较高。

实验三:归并排序归并排序是一种稳定的排序算法,它的原理是将待排序的数据分成若干个子序列,然后将子序列两两合并,直到最终得到有序的结果。

我们同样使用Python 语言实现了归并排序算法,并进行了相同规模数据的排序实验。

实验结果显示,归并排序的时间复杂度相对较低。

当数据规模为10时,排序所需的时间约为0.0008秒;而当数据规模增加到1000时,排序所需的时间仅为0.03秒左右。

这说明归并排序同样适用于大规模数据的排序,其效率较高。

讨论与结论:通过以上实验,我们可以得出以下结论:1. 冒泡排序虽然简单易懂,但对于大规模数据的排序效率较低,不适用于实际应用。

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

实验五排序实验目的: 掌握几种排序的思想及算法问题分析:(一)直接插入排序1. 排序思想将待排序的记录Ri,插入到已排好序的记录表R1, R2 ,…., Ri-1中,得到一个新的、记录数增加1的有序表。

直到所有的记录都插入完为止。

设待排序的记录顺序存放在数组R[1…n]中,在排序的某一时刻,将记录序列分成两部分:◆R[1…i-1]:已排好序的有序部分;◆R[i…n]:未排好序的无序部分。

显然,在刚开始排序时,R[1]是已经排好序的。

2 . 算法实现void straight_insert_sort(Sqlist R){ int i, j ;for (i=2; i<=n; i++){ R[0]=R[i]; j=i-1; /*设置哨兵*/while( LT(R[0].key, R[j].key) ){ R[j+1]=R[j];j--;} /* 查找插入位置*/R[j+1]=R[0]; /* 插入到相应位置*/}}(二)希尔排序1. 排序思想①先取一个正整数d1(d1<n)作为第一个增量,将全部n个记录分成d1组,把所有相隔d1的记录放在一组中,即对于每个k(k=1, 2, … d1),R[k], R[d1+k], R[2d1+k] , …分在同一组中,在各组内进行直接插入排序。

这样一次分组和排序过程称为一趟希尔排序;②取新的增量d2<d1,重复①的分组和排序操作;直至所取的增量di=1为止,即所有记录放进一个组中排序为止。

2. 算法实现先给出一趟希尔排序的算法,类似直接插入排序。

void shell_pass(Sqlist R, int d)/* 对顺序表L进行一趟希尔排序, 增量为d */{ int j, k ;for (j=d+1; j<=n; j++){ R[0]=R[j] ; /* 设置监视哨兵*/k=j-d ;while (k>0&&LT(R[0].key, R[k].key) ){ R[k+d]=R[k] ; k=k-d ; }R[k+d]=R[0] ;}}然后在根据增量数组dk进行希尔排序。

void shell_sort(Sqlist R, int dk[], int t)/* 按增量序列dk[0 … t-1],对顺序表L进行希尔排序*/{ int m ;for (m=0; m<t; m++)shll_pass(R, dk[m]) ;}增量序列取法◆无除1以外的公因子;◆最后一个增量值必须为1。

(三)简单选择排序1. 排序思想基本操作是:通过n-i次关键字间的比较,从n-i+1个记录中选取关键字最小的记录,然后和第i个记录进行交换,i=1, 2, … n-1 。

2. 算法实现void simple_selection_sort(Sqlist R){ int i, j,k;for (i=1; i<n; i++){ k=i ;for (j=i+1; j<=n;j++)if ( LT(R[j].key, R[k].key) ) k=j ;if (k!=i) /* 记录交换*/{ R[0]=R[k]; R[k]=R[i];R[i]=R[0];}}}(四)堆排序1. 排序思想①对一组待排序的记录,按堆的定义建立堆;②将堆顶记录和最后一个记录交换位置,则前n-1个记录是无序的,而最后一个记录是有序的;③堆顶记录被交换后,前n-1个记录不再是堆,需将前n-1个待排序记录重新组织成为一个堆,然后将堆顶记录和倒数第二个记录交换位置,即将整个序列中次小关键字值的记录调整(排除)出无序区;④重复上述步骤,直到全部记录排好序为止。

排序过程中,若采用小根堆,排序后得到的是递减序列;若采用大根堆,排序后得到的是递增序列。

堆的调整——筛选⑴堆的调整思想输出堆顶元素之后,以堆中最后一个元素替代之;然后将根结点值与左、右子树的根结点值进行比较,并与其中小者进行交换;重复上述操作,直到是叶子结点或其关键字值小于等于左、右子树的关键字的值,将得到新的堆。

称这个从堆顶至叶子的调整过程为“筛选”,如图10-10所示。

⑵堆调整算法实现void Heap_adjust(Sqlist R, int low, int high)/* R[low..high]中记录关键字除R[low].key均满足堆定义*//* 调整R[low]的位置使之成为小根堆*/{ R[0]=R[low] ; /*临时保存调整点R[low] */for (k=2*low; k<=high; k=k*2){ if ((k<high)&&(LT(R[k+1].key, R[k].key))k++ ; /* 选择左、右孩子中关键字的最小者*/if ( LT(R[k].key, R[0].key) ){ R[j]=R[k] ; low=k ; }else break ;}R[j]=R[0] ;}2. 堆的建立利用筛选算法,可以将任意无序的记录序列建成一个堆,设R[1],R[2], …,R[n]是待排序的记录序列。

将二叉树的每棵子树都筛选成为堆。

只有根结点的树是堆。

第⌊n/2⌋个结点之后的所有结点都没有子树,即以第⎣n/2⎦个结点之后的结点为根的子树都是堆。

因此,以这些结点为左、右孩子的结点,其左、右子树都是堆,则进行一次筛选就可以成为堆。

同理,只要将这些结点的直接父结点进行一次筛选就可以成为堆…。

只需从第⎣n/2⎦个记录到第1个记录依次进行筛选就可以建立堆。

3.堆排序算法实现堆的根结点是关键字最小的记录,输出根结点后,是以序列的最后一个记录作为根结点,而原来堆的左、右子树都是堆,则进行一次筛选就可以成为堆。

void Heap_Sort(Sqlist R){ int i ;for (i=n/2; i>0;ij--)Heap_adjust(R, i , n) ; /*初始建堆*/for (i=n; i>=1; i--){ R[0]=R[1] ; R[1]=R[i] ;R[i]=R[0] ; /* 堆顶与最后一个交换*/Heap_adjust(R, 1, i-1) ;}}(五)快速排序1. 排序思想通过一趟排序,将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,再分别对这两部分记录进行下一趟排序,以达到整个序列有序。

2. 排序过程设待排序的记录序列是R[s…t] ,在记录序列中任取一个记录(一般取R[s])作为参照(又称为基准或枢轴),以R[s].key为基准重新排列其余的所有记录,方法是:◆所有关键字比基准小的放R[s]之前;◆所有关键字比基准大的放R[s]之后。

以R[s].key最后所在位置i作为分界,将序列R[s…t]分割成两个子序列,称为一趟快速排序。

3. 一趟快速排序方法从序列的两端交替扫描各个记录,将关键字小于基准关键字的记录依次放置到序列的前边;而将关键字大于基准关键字的记录从序列的最后端起,依次放置到序列的后边,直到扫描完所有的记录。

设置指针low,high,初值为第1个和最后一个记录的位置。

设两个变量i,j,初始时令i=low,j=high,以R[low].key作为基准(将R[low]保存在R[0]中) 。

①从j所指位置向前搜索:将R[0].key与R[j].key进行比较:◆若R[0].key≤R[j].key :令j=j-1,然后继续进行比较,直到i=j或R[0].key>R[j].key为止;◆若R[0].key>R[j].key :R[j]⇒R[i],腾空R[j]的位置,且令i=i+1;②从i所指位置起向后搜索:将R[0].key与R[i].key进行比较:◆若R[0].key≥R[i].key :令i=i+1,然后继续进行比较,直到i=j或R[0].key<R[i].key为止;◆若R[0].key<R[i].key :R[i]⇒R[j],腾空R[i]的位置,且令j=j-1;重复①、②,直至i=j为止,i就是R[0](基准)所应放置的位置。

4. 算法实现⑴一趟快速排序算法的实现int quick_one_pass(Sqlist R , int low, int high){ int i=low, j=high ;R[0]=R[i] ; /* R[0]作为临时单元和哨兵*/do {while (LQ(R[0].key, R[j].key)&&(j>i))j-- ;if (j>i) { R[i]=R[j] ; i++; }while (LQ(R[i].key, R[0].key)&&(j>i))i++ ;if (j>i) { R[j]=R[i] ; j--; }} while(i!=j) ; /* i=j时退出扫描*/R[i]=R[0] ; return(i) ;}⑵快速排序算法实现当进行一趟快速排序后,采用同样方法分别对两个子序列快速排序,直到子序列记录个为1为止。

①递归算法void quick_Sort(Sqlist R , int low, int high){ int k ;if (low<high){ k=quick_one_pass(R, low, high);quick_Sort(R, low, k-1);quick_Sort(R, k+1, high);} /* 序列分为两部分后分别对每个子序列排序*/}②非递归算法void quick_Sort(Sqlist R , int low, int high){ int k , stack[MAX_STACK] , top=0;do { while (low<high){ k=quick_one_pass(R,low,high);stack[++top]=high ; stack[++top]=k+1 ;/* 第二个子序列的上,下界分别入栈*/high=k-1 ;}if (top!=0){ low=stack[top--] ; high=stack[top--] ; }}while (top!=0&&low<high) ;}源程序清单:#include<stdio.h>#include<stdlib.h>#define MAX_SIZE 100typedef struct RecType{int key; //关键字码char otherinfo;//其他域}RecType;typedef struct{RecType R[MAX_SIZE];int n;}Sqlist;void straight_insert_sort(Sqlist L, int n){ //直接插入排序int i,j;for (i=2;i<=n;i++){L.R[0]=L.R[i]; j=i-1;while(L.R[0].key<L.R[j].key){L.R[j+1]=L.R[j];j--;}L.R[j+1]=L.R[0];}for(i=1;i<=n;i++)printf("%d %c\n",L.R[i].key,L.R[i].otherinfo);}void shell_pass(Sqlist &L,int n,int d){ //一趟希尔排序int j, k;for(j=d+1;j<=n;j++){L.R[0]=L.R[j] ;k=j-d;while((k>0)&&(L.R[0].key<L.R[k].key)){L.R[k+d]=L.R[k] ; k=k-d ;}L.R[k+d]=L.R[0];}}void shell_sort(Sqlist &L,int n,int dk[],int t){ //希尔排序int i,j,m;for(m=0;m<t;m++){shell_pass(L,n,dk[m]);for(j=1;j<=n;j++)printf("%3d",L.R[j].key);printf("\n");}for(i=1;i<=n;i++)printf("%d %c\n",L.R[i].key,L.R[i].otherinfo);}void simple_selection_sort(Sqlist L,int n){ //直接选择排序int i,j,k;for(i=1; i<n; i++){k=i;for(j=i+1;j<=n;j++)if(L.R[j].key<L.R[k].key) k=j ;if(k!=i){L.R[0]=L.R[k]; L.R[k]=L.R[i];L.R[i]=L.R[0];}}for(i=1;i<=n;i++)printf("%d %c\n",L.R[i].key,L.R[i].otherinfo);}void Heap_adjust(Sqlist &L, int low, int high){ //堆调整int k;L.R[0]=L.R[low] ;for (k=2*low; k<=high; k=k*2){if ((k<high)&&(L.R[k+1].key<L.R[k].key))k++ ;if (L.R[k].key<L.R[0].key){L.R[low]=L.R[k] ; low=k ; }else break ;}L.R[low]=L.R[0] ;}void Heap_Sort(Sqlist &L,int n){ //堆排序int i,j ;for (i=n/2; i>0;i--)Heap_adjust(L, i , n) ;for (i=n; i>=1; i--){L.R[0]=L.R[1] ; L.R[1]=L.R[i] ;L.R[i]=L.R[0] ;Heap_adjust(L, 1, i-1) ;for(j=n;j>=1;j--)printf("%3d",L.R[j].key);printf("\n");}for(i=n;i>=1;i--)printf("%d %c\n",L.R[i].key,L.R[i].otherinfo);}int quick_one_pass(Sqlist &L, int low, int high){ //一趟快速排序int i=low, j=high ;L.R[0]=L.R[i] ;do{while ((L.R[0].key<=L.R[j].key)&&(j>i))j-- ;if (j>i) { L.R[i]=L.R[j] ; i++; }while ((L.R[i].key<=L.R[0].key)&&(j>i))i++ ;if (j>i) { L.R[j]=L.R[i] ; j--; }}while(i!=j) ;L.R[i]=L.R[0] ; return(i) ;}void quick_Sort(Sqlist &L,int n,int low,int high){ //快速排序int i,k ;if (low<high){k=quick_one_pass(L, low, high);quick_Sort(L, n, low, k-1);quick_Sort(L, n, k+1, high);}for(i=1;i<=n;i++)printf("%3d",L.R[i].key);printf("\n");}void main(){int a,i,t;Sqlist L;int dk[30];printf("1.建表\n2.直接插入排序\n3.Shell排序\n4.直接选择排序\n5.堆排序\n6.快速排序\n0.退出\n");while(1){printf("\n请选择:");scanf("%d",&a); getchar();switch(a){case 1: printf("请输入记录数量n:");scanf("%d",&L.n);for(i=1;i<L.n+1;i++){printf("请输入关键字码与数据:");scanf("%d,%c",&L.R[i].key,&L.R[i].otherinfo);}break;case 2:straight_insert_sort(L,L.n);break;case 3:printf("请输入增量数量t:");scanf("%d",&t);for(i=0;i<t;i++){printf("请输入增量:");scanf("%d",&dk[i]);}shell_sort(L,L.n,dk,t);break;case 4:simple_selection_sort(L,L.n);break;case 5:Heap_Sort(L,L.n);break;case 6:quick_Sort(L,L.n,1,L.n);break;case 0: exit(0);}}}运行结果:。

相关文档
最新文档