c语言各种排序法详细讲解

合集下载

C语言数组的五种简单排序,选择法排序,冒泡法排序、交换法排序、插入法排序、折半法排序

C语言数组的五种简单排序,选择法排序,冒泡法排序、交换法排序、插入法排序、折半法排序

C语⾔数组的五种简单排序,选择法排序,冒泡法排序、交换法排序、插⼊法排序、折半法排序⽂章⽬录1、选择法排序选择法排序是指每次选择索要排序的数组中的最⼩值(这⾥是由⼩到⼤排序,如果是由⼤到⼩排序则需要选择最⼤值)的数组元素,将这些数组元素的值与前⾯没有进⾏排序的数组元素值进⾏互换代码实现需要注意的是:声明⼀个数组和两个整形变量,数组⽤于存储输⼊的数字,⽽整形变量⽤于存储最⼩的数组元素的数值与该元素的位置,在我的代码中实现为a[] temp position。

代码具体如下#include<stdio.h>int main(){int m,n,k;printf("please input the length of the array:");scanf("%d",&k);int a[k];int temp;int position;printf("please input the number of the array:\n");for(m=0;m<k;m++){printf("a[%d]=",m+1);scanf("%d",&a[m]);}/*从⼩到⼤排序*/for(m=0;m<k-1;m++){temp=a[m]; //设置当前的值为最⼩值position=m; //记录当前的位置for(n=m+1;n<k;n++){if(a[n]<temp){temp=a[n]; //如果找到⽐当前的还要⼩的数值,则更换最⼩的数值与位置position=n;}}a[position]=a[m];a[m]=temp;}for(m=0;m<k;m++){printf("%d\t",a[m]);}return 0;}结果如下2、冒泡法排序冒泡法排序就是值在排序时,每次⽐较数组中相邻的两个数组元素的值,将⽐较⼩的(从⼩到⼤排序算法,如果是从⼤到⼩排序算法就是将较⼤的数排在较⼩的数前⾯)排在⽐较⼤的前⾯在代码实现的过程中:声明⼀个数组与⼀个整型变量,数组⽤于存放数据元素,整型变量⽤于交换时作为中间变量。

c语言中排序的各种方法解析

c语言中排序的各种方法解析

c语言中排序的各种方法解析一、引言在计算机编程中,排序是一个重要的操作,它按照一定的顺序排列数据元素,使得数据元素按照从小到大的顺序排列。

在C语言中,有多种方法可以实现排序,包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。

这些排序算法都有各自的优缺点,适合不同的应用场景。

二、冒泡排序冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。

算法步骤:1. 比较相邻的元素。

如果第一个比第二个大(升序),就交换它们两个。

2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。

这步做完后,最后的元素会是最大的数。

3. 针对所有的元素重复以上的步骤,除了最后一个。

4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

三、选择排序选择排序是一种简单直观的排序算法。

它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。

算法步骤:1. 在未排序序列中找到最小元素,存放到排序序列的起始位置。

2. 再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。

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

四、插入排序插入排序的工作方式是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。

插入排序在实现上通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

五、快速排序快速排序使用了分治的原则,它在每一层划分都比前面方法有所改进和精进,当切分到两边的子序列长度都大于某个值时,或者一个大于一个小于这个值时再进行交换的操作来结束此层的递归过程。

这层的结果又成为下一层的两个子数组来处理,最后就得到递归式的最终结果。

使用C语言实现12种排序方法

使用C语言实现12种排序方法

使⽤C语⾔实现12种排序⽅法⽬录1.冒泡排序2.插⼊排序3.折半插⼊排序4.希尔排序5.选择排序6.鸡尾酒排序7.堆排序8.快速排序9.归并排序10.计数排序11.桶排序12.基数排序1.冒泡排序思路:⽐较相邻的两个数字,如果前⼀个数字⼤,那么就交换两个数字,直到有序。

时间复杂度O(n^2),稳定性:这是⼀种稳定的算法。

代码实现:void bubble_sort(int arr[],size_t len){size_t i,j;for(i=0;i<len;i++){bool hasSwap = false; //优化,判断数组是否已经有序,如果有序可以提前退出循环for(j=1;j<len-i;j++){ //这⾥j<len-i是因为最后⾯的肯定都是最⼤的,不需要多进⾏⽐较if(arr[j-1]>arr[j]){ //如果前⼀个⽐后⼀个⼤swap(&arr[j-1],&arr[j]); //交换两个数据hasSwap = true;}}if(!hasSwap){break;}}}2.插⼊排序思路:把⼀个数字插⼊⼀个有序的序列中,使之仍然保持有序,如对于需要我们进⾏排序的数组,我们可以使它的前i个数字有序,然后再插⼊i+1个数字,插⼊到合适的位置使之仍然保持有序,直到所有的数字有序。

时间复杂度:O(n^2) 稳定性:稳定的算法代码实现:void insert_sort(int arr[],int len){int i,j;for(i=1;i<len;i++){int key = arr[i]; //记录当前需要插⼊的数据for(j= i-1;i>=0&&arr[j]>key;j--){ //找到插⼊的位置arr[j+1] = arr[j]; //把需要插⼊的元素后⾯的元素往后移}arr[j+1] = key; //插⼊该元素}}3.折半插⼊排序思路:本质上是插⼊排序,但是通过半分查找法找到插⼊的位置,让效率稍微快⼀点。

C语言八大排序算法

C语言八大排序算法

C语⾔⼋⼤排序算法C语⾔⼋⼤排序算法,附动图和详细代码解释!来源:C语⾔与程序设计、⽵⾬听闲等⼀前⾔如果说各种编程语⾔是程序员的招式,那么数据结构和算法就相当于程序员的内功。

想写出精炼、优秀的代码,不通过不断的锤炼,是很难做到的。

⼆⼋⼤排序算法排序算法作为数据结构的重要部分,系统地学习⼀下是很有必要的。

1、排序的概念排序是计算机内经常进⾏的⼀种操作,其⽬的是将⼀组“⽆序”的记录序列调整为“有序”的记录序列。

排序分为内部排序和外部排序。

若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序。

反之,若参加排序的记录数量很⼤,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序。

2、排序分类⼋⼤排序算法均属于内部排序。

如果按照策略来分类,⼤致可分为:交换排序、插⼊排序、选择排序、归并排序和基数排序。

如下图所⽰:3、算法分析1.插⼊排序*直接插⼊排序*希尔排序2.选择排序*简单选择排序*堆排序3.交换排序*冒泡排序*快速排序4.归并排序5.基数排序不稳定排序:简单选择排序,快速排序,希尔排序,堆排序稳定排序:冒泡排序,直接插⼊排序,归并排序,奇数排序1、插⼊排序将第⼀个和第⼆个元素排好序,然后将第3个元素插⼊到已经排好序的元素中,依次类推(插⼊排序最好的情况就是数组已经有序了)因为插⼊排序每次只能操作⼀个元素,效率低。

元素个数N,取奇数k=N/2,将下标差值为k的数分为⼀组(⼀组元素个数看总元素个数决定),在组内构成有序序列,再取k=k/2,将下标差值为k的数分为⼀组,构成有序序列,直到k=1,然后再进⾏直接插⼊排序。

3、简单选择排序选出最⼩的数和第⼀个数交换,再在剩余的数中⼜选择最⼩的和第⼆个数交换,依次类推4、堆排序以升序排序为例,利⽤⼩根堆的性质(堆顶元素最⼩)不断输出最⼩元素,直到堆中没有元素1.构建⼩根堆2.输出堆顶元素3.将堆低元素放⼀个到堆顶,再重新构造成⼩根堆,再输出堆顶元素,以此类推5、冒泡排序改进1:如果某次冒泡不存在数据交换,则说明已经排序好了,可以直接退出排序改进2:头尾进⾏冒泡,每次把最⼤的沉底,最⼩的浮上去,两边往中间靠16、快速排序选择⼀个基准元素,⽐基准元素⼩的放基准元素的前⾯,⽐基准元素⼤的放基准元素的后⾯,这种动作叫分区,每次分区都把⼀个数列分成了两部分,每次分区都使得⼀个数字有序,然后将基准元素前⾯部分和后⾯部分继续分区,⼀直分区直到分区的区间中只有⼀个元素的时候,⼀个元素的序列肯定是有序的嘛,所以最后⼀个升序的序列就完成啦。

C语言入门必学—10个经典C语言算法

C语言入门必学—10个经典C语言算法

C语言入门必学—10个经典C语言算法C语言是一种广泛使用的编程语言,具有高效、灵活和易学的特点。

它不仅在软件开发中被广泛应用,也是计算机科学专业的必修课。

在学习C语言的过程中,掌握一些经典的算法是非常重要的。

本文将介绍10个经典C语言算法,帮助读者更好地了解和掌握C语言。

一、冒泡排序算法(Bubble Sort)冒泡排序算法是最简单、也是最经典的排序算法之一。

它通过不断比较相邻的元素并交换位置,将最大(或最小)的元素逐渐“冒泡”到数组的最后(或最前)位置。

二、选择排序算法(Selection Sort)选择排序算法是一种简单但低效的排序算法。

它通过不断选择最小(或最大)的元素,并与未排序部分的第一个元素进行交换,将最小(或最大)的元素逐渐交换到数组的前面(或后面)。

三、插入排序算法(Insertion Sort)插入排序算法是一种简单且高效的排序算法。

它通过将数组分为已排序和未排序两个部分,依次将未排序部分的元素插入到已排序部分的合适位置。

四、快速排序算法(Quick Sort)快速排序算法是一种高效的排序算法。

它采用了分治的思想,通过将数组分为较小和较大两部分,并递归地对两部分进行排序,最终达到整个数组有序的目的。

五、归并排序算法(Merge Sort)归并排序算法是一种高效的排序算法。

它采用了分治的思想,将数组一分为二,递归地对两个子数组进行排序,并将结果合并,最终得到有序的数组。

六、二分查找算法(Binary Search)二分查找算法是一种高效的查找算法。

它通过不断将查找范围折半,根据中间元素与目标值的大小关系,缩小查找范围,最终找到目标值所在的位置。

七、递归算法(Recursive Algorithm)递归算法是一种通过自我调用的方式解决问题的算法。

在C语言中,递归算法常用于解决树的遍历、问题分解等情况。

八、斐波那契数列算法(Fibonacci Sequence)斐波那契数列是一列数字,其中每个数字都是前两个数字的和。

c语言实现简单排序(8种方法)

c语言实现简单排序(8种方法)

#include<stdio.h>#include<stdlib.h>//冒泡排序voidbubleSort(int data[], int n);//快速排序voidquickSort(int data[], int low, int high); intfindPos(int data[], int low, int high);//插入排序voidbInsertSort(int data[], int n);//希尔排序voidshellSort(int data[], int n);//选择排序voidselectSort(int data[], int n);//堆排序voidheapSort(int data[], int n);void swap(int data[], inti, int j);voidheapAdjust(int data[], inti, int n);//归并排序voidmergeSort(int data[], int first, int last);void merge(int data[], int low, int mid, int high); //基数排序voidradixSort(int data[], int n);intgetNumPos(intnum, intpos);int main() {int data[10] = {43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; inti;printf("原先数组:");for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");/*printf("冒泡排序:");bubleSort(data, 10);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");printf("快速排序:");quickSort(data, 0, 9);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");printf("插入排序:");bInsertSort(data,10);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");printf("希尔排序:");shellSort(data, 10);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");printf("选择排序:");selectSort(data, 10);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; inti;printf("原先数组:");int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79}; for(i=1;i<11;i++) {printf("%d ", data[i]);}printf("\n");printf(" 堆排序:");heapSort(data, 10);for(i=1;i<11;i++) {printf("%d ", data[i]);}printf("\n");printf("归并排序:");mergeSort(data, 0, 9);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");*/printf("基数排序:");radixSort(data, 10);for(i=0;i<10;i++) {printf("%d ", data[i]);}printf("\n");return 0;}/*--------------------冒泡排序---------------------*/ voidbubleSort(int data[], int n) {inti,j,temp;//两个for循环,每次取出一个元素跟数组的其他元素比较//将最大的元素排到最后。

数组排序函数c语言

数组排序函数c语言

数组排序函数c语言数组排序函数是计算机编程中常用的一种函数,它的作用是将一个数组中的元素按照一定的规则进行排序。

在C语言中,有多种方法可以实现数组的排序,包括冒泡排序、选择排序、插入排序、快速排序等。

本文将介绍这些排序算法的原理和实现方式。

一、冒泡排序冒泡排序是一种简单直观的排序算法,它的原理是通过比较相邻元素的大小,将较大的元素逐渐“冒泡”到数组的末尾。

具体实现时,我们可以使用两层循环来完成冒泡排序的过程。

外层循环控制比较的轮数,内层循环用于比较相邻元素的大小并进行交换。

经过多轮比较和交换,最终数组中的元素按照从小到大的顺序排列。

二、选择排序选择排序是一种简单但低效的排序算法,它的原理是每次从未排序的元素中选择最小的元素,然后与未排序部分的第一个元素交换位置,这样每一轮都能确定一个最小元素的位置。

具体实现时,我们可以使用两层循环来完成选择排序的过程。

外层循环控制比较的轮数,内层循环用于寻找未排序部分的最小元素并进行交换。

经过多轮比较和交换,最终数组中的元素按照从小到大的顺序排列。

三、插入排序插入排序是一种简单直观的排序算法,它的原理是将一个元素插入到已经排好序的数组中的合适位置。

具体实现时,我们可以使用两层循环来完成插入排序的过程。

外层循环控制待插入的元素,内层循环用于比较已排序部分的元素并进行移动。

经过多轮比较和移动,最终数组中的元素按照从小到大的顺序排列。

四、快速排序快速排序是一种高效的排序算法,它的原理是通过选择一个基准元素,将数组分成两部分,左边部分的元素都小于基准元素,右边部分的元素都大于基准元素,然后递归地对左右两部分进行排序。

具体实现时,我们可以使用递归函数来完成快速排序的过程。

在每一轮排序中,我们选择一个基准元素,将数组分成两部分,并对这两部分进行递归排序。

经过多轮递归排序,最终数组中的元素按照从小到大的顺序排列。

以上是常见的几种数组排序函数的原理和实现方式。

在实际编程中,我们可以根据具体的需求选择合适的排序算法。

C语言奇偶排序算法详解及实例代码

C语言奇偶排序算法详解及实例代码

C语言奇偶排序算法详解及实例代码奇偶排序(Odd-Even Sort)算法是一种简单的排序算法,它可以同时对数组中的奇数和偶数进行排序。

这个算法的原理比较简单,它的思想类似冒泡排序,只不过比较的对象从相邻的两个数变为了相隔一个位置的两个数。

奇偶排序算法的步骤如下:1.将数组分为两个部分,分别存放奇数和偶数。

2.在奇数部分中进行一轮冒泡排序,将较大的数往右移。

3.在偶数部分中进行一轮冒泡排序,将较小的数往左移。

4.重复执行步骤2和步骤3,直到数组完全有序。

下面我们来详细解析奇偶排序算法,并给出一个实例代码。

1. 定义一个函数 `void oddEvenSort(int arr[], int n)`,用于实现奇偶排序。

2. 在函数内部创建两个变量 `sorted` 和 `exchange`,分别表示数组是否已经完全有序和两个相邻元素是否发生交换。

3. 使用一个循环,首先将 `sorted` 和 `exchange` 初始化为`false`。

4. 使用两个嵌套循环,外层循环控制数组两个部分的排序,内层循环控制每个部分的冒泡排序。

5. 内层循环的初始条件为 `j = i % 2`,其中 `i` 表示当前循环的次数。

当 `i` 为偶数时,`j` 为 0,表示要对偶数部分排序;当`i` 为奇数时,`j` 为 1,表示要对奇数部分排序。

6. 内层循环用于对数组中的一部分进行冒泡排序,如果发生交换,则将 `exchange` 设置为 `true`。

冒泡排序的过程和一般的冒泡排序算法类似。

7. 当内层循环结束后,判断 `exchange` 是否为 `false`,如果是,则说明数组已经完全有序,将 `sorted` 设置为 `true`,并退出外层循环。

8. 最后,在函数末尾添加一个循环,用于输出排序后的数组。

下面是完整的实例代码:```c#include <stdio.h>void swap(int *a, int *b){int temp = *a;*a = *b;*b = temp;}void oddEvenSort(int arr[], int n)int sorted = 0; // 数组是否已经完全有序int exchange = 0; // 两个相邻元素是否发生交换 while (!sorted){sorted = 1;for (int i = 0; i < n - 1; i++){exchange = 0;int j = i % 2;for (; j < n - 1; j += 2){if (arr[j] > arr[j + 1]){swap(&arr[j], &arr[j + 1]);exchange = 1;sorted = 0;}}if (!exchange){break;}}}}int main(){int arr[] = {9, 2, 7, 4, 5, 6, 3, 8, 1};int n = sizeof(arr) / sizeof(arr[0]);oddEvenSort(arr, n);for (int i = 0; i < n; i++){printf("%d ", arr[i]);}return 0;}```以上是奇偶排序算法的详细解析及一个示例代码。

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

一插入排序1.1 直接插入排序基本思想:每次将一个待排序额记录按其关键码的大小插入到一个已经排好序的有序序列中,直到全部记录排好序。

图解:1.//直接顺序排序2.void InsertSort(int r[], int n)3.{4.for (int i=2; i<n; i++)5. {6. r[0]=r[i]; //设置哨兵7.for (int j=i-1; r[0]<r[j]; j--) //寻找插入位置8. r[j+1]=r[j]; //记录后移9. r[j+1]=r[0];10. }11.for(int k=1;k<n;k++)12. cout<<r[k]<<" ";13. cout<<"\n";14.}1.2 希尔排序基本思想是:先将整个待排序记录序列分割成若干个子序列,在在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。

图解:代码实现:[cpp]view plain copy1.<span style="font-size:14px;">//希尔排序2.void ShellSort(int r[], int n)3.{4.int i;5.int d;6.int j;7.for (d=n/2; d>=1; d=d/2) //以增量为d进行直接插入排序8. {9.for (i=d+1; i<n; i++)10. {11. r[0]=r[i]; //暂存被插入记录12.for (j=i-d; j>0 && r[0]<r[j]; j=j-d)13. r[j+d]=r[j]; //记录后移d个位置14. r[j+d]=r[0];15. }16. }17.for(i=1;i<n;i++)18. cout<<r[i]<<" ";19. cout<<"\n";20.}</span>二交换排序2.1 起泡排序起泡排序是交换排序中最简单的排序方法,其基本思想是:两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。

图解:代码实现:[cpp]view plain copy1.<span style="font-size:14px;">//起泡排序2.void BubbleSort(int r[], int n)3.{4.int temp;5.int exchange;6.int bound;7. exchange=n-1; //第一趟起泡排序的范围是r[0]到r[n-1]8.while (exchange) //仅当上一趟排序有记录交换才进行本趟排序9. {10. bound=exchange;11. exchange=0;12.for (int j=0; j<bound; j++) //一趟起泡排序13.if (r[j]>r[j+1])14. {15. temp=r[j];16. r[j]=r[j+1];17. r[j+1]=temp;18. exchange=j; //记录每一次发生记录交换的位置19. }20. }21.for(int i=0;i<n;i++)22. cout<<r[i]<<" ";23. cout<<"\n";24.}</span>2.2快速排序基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

图解:代码实现:[cpp] view plain copy 1. //快速排序一次划分2. int Partition(int r[], int first, int end)3.{4.int i=first; //初始化5.int j=end;6.int temp;7.8.while (i<j)9. {10.while (i<j && r[i]<= r[j])11. j--; //右侧扫描12.if (i<j)13. {14. temp=r[i]; //将较小记录交换到前面15. r[i]=r[j];16. r[j]=temp;17. i++;18. }19.while (i<j && r[i]<= r[j])20. i++; //左侧扫描21.if (i<j)22. {23. temp=r[j];24. r[j]=r[i];25. r[i]=temp; //将较大记录交换到后面26. j--;27. }28. }29.return i; //i为轴值记录的最终位置30.}31.32.//快速排序33.void QuickSort(int r[], int first, int end)34.{35.if (first<end)36. { //递归结束37.int pivot=Partition(r, first, end); //一次划分38. QuickSort(r, first, pivot-1);//递归地对左侧子序列进行快速排序39. QuickSort(r, pivot+1, end); //递归地对右侧子序列进行快速排序40. }41.42.}三选择排序3.1 简单选择排序基本思想:设所排序序列的记录个数为n。

i取1,2,…,n-1,从所有n-i+1个记录(Ri,Ri+1,…,Rn)中找出排序码最小的记录,与第i个记录交换。

执行n-1趟后就完成了记录序列的排序。

图解:代码实现:[cpp]view plain copy1.//简单选择排序2.void SelectSort(int r[ ], int n)3.{4.int i;5.int j;6.int index;7.int temp;8.for (i=0; i<n-1; i++) //对n个记录进行n-1趟简单选择排序9. {10. index=i;11.for (j=i+1; j<n; j++) //在无序区中选取最小记录12.if (r[j]<r[index])13. index=j;14.if (index!=i)15. {16. temp=r[i];17. r[i]=r[index];18. r[index]=temp;19. }20. }21.for(i=0;i<n;i++)22. cout<<r[i]<<" ";23. cout<<"\n";24.}3.2 堆排序堆的定义堆是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子结点的值(小根堆);或者每个结点的值都大于或等于其左右孩子结点的值(大根堆)。

大根堆和小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。

根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。

注意:①堆中任一子树亦是堆。

②以上讨论的堆实际上是二叉堆(BinaryHeap),类似地可定义k叉堆。

假设当前要筛选结点的编号为k,堆中最后一个结点的编号为m,并且结点k的左右子树均是堆(即r[k+1] ~ r[m]满足堆的条件),则筛选算法用伪代码可描述为:具体的筛选代码如下:[cpp]view plain copy1.//筛选法调整堆2.void Sift(int r[], int k, int m)3.{4.5.int i;6.int j;7.int temp;8. i=k;9. j=2*i+1; //置i为要筛的结点,j为i的左孩子10.while (j<=m) //筛选还没有进行到叶子11. {12.if (j<m && r[j]<r[j+1])13. j++; //比较i的左右孩子,j为较大者14.if (r[i]>r[j]) break; //根结点已经大于左右孩子中的较大者15.else16. {17. temp=r[i];18. r[i]=r[j];19. r[j]=temp; //将根结点与结点j交换20. i=j;21. j=2*i+1; //被筛结点位于原来结点j的位置22. }23. }24.}堆排序堆排序的基本思想是:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者即堆顶记录,然后将它从堆中移走(通常将堆顶记录和堆中最后一个记录交换),并将剩余的记录再调整成堆,这样又找出了次大的记录,以此类推,直到堆中只有一个记录为止。

(1)用大根堆排序的基本思想①先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区②再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。

然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。

……直到无序区只有一个元素为止。

(2)大根堆排序算法的基本操作:①初始化操作:将R[1..n]构造为初始堆;②每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。

注意:①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。

②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。

堆排序和直接选择排序相反:在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止代码实现:[cpp]view plain copy1.//堆排序2.void HeapSort(int r[ ], int n)3.{4.5.int i;6.int temp;7.for (i=n/2; i>=0; i--) //初始建堆,从最后一个非终端结点至根结点8. Sift(r, i, n) ;9.for (i=n-1; i>0; i--) //重复执行移走堆顶及重建堆的操作10. {11. temp=r[i];12. r[i]=r[0];13. r[0]=temp;14. Sift(r, 0, i-1);15. }16.for(i=0;i<n;i++)17. cout<<r[i]<<" ";18. cout<<"\n";19.}四归并排序二路归并排序基本思想:将若干个有序序列进行两两归并,直至所有待排序记录都在一个有序序列为止。

相关文档
最新文档