各种排序原理及其C语言实现
- 格式:doc
- 大小:138.00 KB
- 文档页数:10
c语言中排序的各种方法解析一、引言在计算机编程中,排序是一个重要的操作,它按照一定的顺序排列数据元素,使得数据元素按照从小到大的顺序排列。
在C语言中,有多种方法可以实现排序,包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
这些排序算法都有各自的优缺点,适合不同的应用场景。
二、冒泡排序冒泡排序是一种简单的排序算法,它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
算法步骤:1. 比较相邻的元素。
如果第一个比第二个大(升序),就交换它们两个。
2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
这步做完后,最后的元素会是最大的数。
3. 针对所有的元素重复以上的步骤,除了最后一个。
4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
三、选择排序选择排序是一种简单直观的排序算法。
它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
算法步骤:1. 在未排序序列中找到最小元素,存放到排序序列的起始位置。
2. 再从剩余未排序元素中继续寻找最小元素,然后放到已排序序列的末尾。
3. 以此类推,直到所有元素均排序完毕。
四、插入排序插入排序的工作方式是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
五、快速排序快速排序使用了分治的原则,它在每一层划分都比前面方法有所改进和精进,当切分到两边的子序列长度都大于某个值时,或者一个大于一个小于这个值时再进行交换的操作来结束此层的递归过程。
这层的结果又成为下一层的两个子数组来处理,最后就得到递归式的最终结果。
插入排序、归并排序、堆排序的C实现。
如有疑问请联系QQ:631785485,我们一起学习。
1.插入排序/******************************************Insert_sort.cpp*实现对输入的数进行快速排序******************************************/#include <stdio.h>#include <stdlib.h>#define M 100void Quick_asc(int *a,const int size);void Quick_desc(int *a,const int size);void output(const int *a,const int size);int main(void){int a[]={9,8,7,6,5,4,3,2,1,0};int size;char quit;char c;size=sizeof(a)/sizeof(int);printf("\n************测**********试**************\n");printf("* 排序前:");output(a,size);printf("* 升序:");Quick_asc(a, size);output(a,size);printf("* 降序:");Quick_desc(a, size);output(a,size);printf("********测*****试*****结*****束*********\n\n");/***********************************//***************自输入模块**********//***********************************/do{printf("\n*************************输入************************\n");printf("提示:请输入要排序的数;中间用空格隔开;回车结束输入!\n\n>");int b[M];volatile int i=0;while((0==i || getchar()!='\n')){scanf("%d",&b[i++]);}printf("\n****************************************");printf("\n排序前:");output(b,i);printf("\n升序:");Quick_asc(b,i);output(b,i);printf("\n降序:");Quick_desc(b,i);output(b,i);printf("****************************************\n");printf("\n按任意键继续!Q键退出!\n>");quit=getchar();while(c=getchar()!='\n' && c!=EOF);system("cls");}while(quit!='Q' && 'q'!=quit);return 0;}//end main//自定义输出函数void output(const int *a,const int size){for(int k=0; k<size; k++){printf("%d ",*(a+k));}printf("\n");}//升序排列void Quick_asc(int *a,const int size){int key;int i, j;for(j=1; j<size; j++){key=*(a+j);i=j-1;while(i>=0 && *(a+i)>key){*(a+i+1)=*(a+i);--i;}*(a+i+1)=key;}}//降序排列void Quick_desc(int *a,const int size) {int key;int i, j;for(j=1; j<size; j++){key=*(a+j);i=j-1;while(i>=0 && *(a+i)<key){*(a+i+1)=*(a+i);--i;}*(a+i+1)=key;}}2.归并排序/************************************Merge_sort.cpp*归并排序的实现************************************/#include <stdio.h>#include <stdlib.h>#define M 100void output(const int *a,const int size); void merge(int *a, int p, int q, int r); void merge_sort(int *a, int p1, int r1); int main(){int a[]={9,8,7,6,5,4,3,2,1,0};char c;int size;size=sizeof(a)/sizeof(int);//归并排序printf("*******************归并排序测试*****************\n");printf("排序前:");output(a,size);merge_sort(a,0,size-1);//归并排序函数调用printf("排序后:");output(a,size);/*******************************************自定义输入模块******************************************/while(true){printf("******************************************************\n" );printf("提示:请输入要排序的数;中间用空格隔开;回车结束输入!\n\n>");int b[M];int i=0;while(0==i || (c=getchar())!='\n'){if(!(scanf("%d",&b[i++]))){i=0;printf("输入有误,请重新输入!");system("pause");system("cls");while(c=getchar()!='\n' && c!=EOF);printf("******************************************************\n" );printf("提示:请输入要排序的数;中间用空格隔开;回车结束输入!\n\n>");continue;}}printf("排序前:");output(b,i);printf("排序后:");merge_sort(b,0,i-1);output(b,i);printf("\n******************************************************\ n");printf("按Q退出,任意键继续!\n>");if((c=getchar())=='Q'||c=='q'){exit(0);}else{//清空输入流while(c=getchar()!='\n' && c!=EOF);}system("cls");}return 0;}//end main()void output(const int *a,const int size){for(int k=0; k<size; k++){printf("%d ",*(a+k));}printf("\n");}//归并排序二分void merge_sort(int *a, int p, int r){if(p<r){int q=(p+r)/2;merge_sort(a, p, q);merge_sort(a, q+1, r);merge(a, p, q, r);}}//end merge_sort()//归并排序//a为数的首地址,p为数的起始位置,q二分的位置,r结束的位置。
数组排序c语言数组排序方法在C语言中,可以使用多种排序算法对数组进行排序。
常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序等。
下面将详细介绍这些排序算法的原理、实现以及时间复杂度。
1. 冒泡排序(Bubble Sort):冒泡排序是一种简单的排序算法,其基本思想是重复地在相邻的元素之间进行比较和交换,将最大的元素逐渐“浮”到数组的尾部。
具体实现过程如下:cvoid bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-1-i; j++) {if (arr[j] > arr[j+1]) {交换相邻元素int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}冒泡排序的时间复杂度为O(n^2),其中n为数组长度。
2. 选择排序(Selection Sort):选择排序也是一种简单的排序算法,其基本思想是每次从未排序的部分中选取最小(或最大)的元素,放到已排序部分的末尾。
具体实现过程如下:cvoid selectionSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {int minIndex = i;for (int j = i+1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}将最小元素交换到已排序部分的末尾int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}选择排序的时间复杂度为O(n^2)。
3. 插入排序(Insertion Sort):插入排序的基本思想是将数组分为已排序和未排序两部分,每次从未排序部分选择一个元素,插入到已排序部分的正确位置。
使⽤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语⾔与程序设计、⽵⾬听闲等⼀前⾔如果说各种编程语⾔是程序员的招式,那么数据结构和算法就相当于程序员的内功。
想写出精炼、优秀的代码,不通过不断的锤炼,是很难做到的。
⼆⼋⼤排序算法排序算法作为数据结构的重要部分,系统地学习⼀下是很有必要的。
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语言数字从大到小排列C语言数字从大到小排列C语言中,数字的排序是程序员需要掌握的计算机技能之一。
下面将介绍如何使用C语言编写程序来实现数字从大到小的排序。
I. 程序思路1. 输入需要排序的数字,将其存储在数组中;2. 从数组中选择一个数字作为基准点,将比基准点小的数字放在基准点左边,比基准点大的数字放在基准点右边;3. 对基准点左边和右边的数字重复第2步,直到所有数字都排列完成。
II. 编程实现1. 定义函数来实现数字排序:```void sort(int arr[], int left, int right){int i, j, pivot, temp;if (left < right) {pivot = left;i = left;j = right;while (i < j) {while (arr[i] >= arr[pivot] && i < right)i++;while (arr[j] < arr[pivot])j--;if (i < j) {temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}temp = arr[pivot];arr[pivot] = arr[j];arr[j] = temp;sort(arr, left, j - 1);sort(arr, j + 1, right);}}```2. 在主函数中输入需要排序的数字,并输出排序结果:```int main(){int arr[100], i, n;printf("请输入数字的个数:");scanf("%d", &n);for (i = 0; i < n; i++) {printf("请输入第 %d 个数字:", i + 1);scanf("%d", &arr[i]);}sort(arr, 0, n - 1);printf("数字按从大到小排列的结果:\n");for (i = 0; i < n; i++)printf("%d ", arr[i]);return 0;}```在上述代码中,sort函数使用快速排序算法实现数字从大到小的排列。
起泡法排序c语言起泡法排序c语言起泡法排序是一种基本的排序算法,也称为冒泡排序。
它的原理是不断比较相邻两个元素的大小,如果前面的元素大于后面的元素,则交换它们。
这样一趟下来,最大(或最小)的元素就会被排到最后(或最前)。
1. 算法步骤起泡法排序算法步骤如下:1. 从数组的第一个元素开始,依次比较相邻两个元素的大小。
2. 如果前面的元素大于后面的元素,则交换它们。
3. 继续比较下一对相邻元素,直到比较到数组末尾。
4. 重复上述步骤,直到所有元素都被排好序。
2. 代码实现以下是使用C语言实现起泡法排序算法的代码:```cvoid bubbleSort(int arr[], int n){int i, j;for(i = 0; i < n-1; i++){for(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;}}}}```该函数接受一个整数数组和数组长度作为参数,并将数组按升序排序。
它使用两个嵌套的循环来比较相邻的元素,并在必要时交换它们。
3. 时间复杂度起泡法排序算法的时间复杂度为O(n^2),其中n是数组中元素的数量。
这是因为该算法需要进行n-1趟排序,每趟排序需要比较n-i-1对相邻元素,并在必要时交换它们。
4. 稳定性起泡法排序算法是一种稳定的排序算法。
这意味着如果数组中有两个相等的元素,它们在排序后仍然保持原来的顺序。
5. 优化虽然起泡法排序算法是一种简单而有效的算法,但它也有一些缺点。
其中最明显的缺点是它的时间复杂度较高,当数组规模很大时,效率会非常低下。
为了提高效率,可以对起泡法排序算法进行一些优化。
以下是几种常见的优化方法:(1)加入标志位:如果某一趟扫描没有发生任何交换,则说明数组已经排好序了,可以直接退出循环。
(2)记录最后一次交换位置:由于每一趟扫描都会将当前未排好序部分中最大(或最小)值移到末尾(或开头),因此可以记录最后一次交换位置,以此来确定下一趟扫描的范围。
C语言中的算法实现算法是计算机科学中非常重要的概念,它是解决问题的一系列步骤或指令集。
在C语言中,我们可以使用不同的方法来实现算法。
本文将介绍一些常见的C语言算法实现方式。
一、排序算法1. 冒泡排序冒泡排序是一种简单但效率较低的排序算法。
它通过不断比较相邻的元素,并按照规则交换它们的位置,直到整个序列排序完成。
2. 选择排序选择排序是一种简单而直观的排序算法。
它每次从未排序的序列中选择最小(或最大)的元素,并将其放置在已排序序列的末尾。
3. 插入排序插入排序是一种简单且高效的排序算法。
它通过构建有序序列,对未排序的元素逐个插入到已排序的序列中,直到所有元素都被插入完成。
二、查找算法1. 顺序查找顺序查找是一种简单的查找算法。
它从列表的开头开始逐个比较元素,直到找到目标元素或查找完整个列表。
2. 二分查找二分查找是一种高效的查找算法,但要求列表必须是有序的。
它通过将待查找区域分成两部分,判断目标元素落在哪一部分,从而缩小查找范围,直到找到目标元素或确定不存在。
三、递归算法递归是一种常用的算法设计技巧。
它通过在函数内调用自身来解决相同问题的不同实例。
在C语言中,递归函数需要定义出口条件,以避免无限递归。
四、动态规划算法动态规划是一种用于解决具有重叠子问题和最优子结构性质的问题的方法。
它将问题分解为一系列子问题,并以自底向上的方式求解子问题,最终得到整体问题的解。
在C语言中,可以使用循环、数组和指针等特性来实现动态规划算法,从而有效地解决问题。
五、图算法图是一种用于描述对象之间关系的数据结构,图算法是解决图相关问题的一类算法。
常见的图算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。
六、字符串算法字符串算法用于处理字符串相关的问题,如字符串匹配、编辑距离等。
C语言提供了一系列字符串处理函数,如strlen、strcpy等,可以方便地实现字符串算法。
七、数学算法C语言在数学算法方面提供了丰富的库函数支持,如求平方根、对数、指数等。
数组排序函数c语言数组排序函数是计算机编程中常用的一种函数,它的作用是将一个数组中的元素按照一定的规则进行排序。
在C语言中,有多种方法可以实现数组的排序,包括冒泡排序、选择排序、插入排序、快速排序等。
本文将介绍这些排序算法的原理和实现方式。
一、冒泡排序冒泡排序是一种简单直观的排序算法,它的原理是通过比较相邻元素的大小,将较大的元素逐渐“冒泡”到数组的末尾。
具体实现时,我们可以使用两层循环来完成冒泡排序的过程。
外层循环控制比较的轮数,内层循环用于比较相邻元素的大小并进行交换。
经过多轮比较和交换,最终数组中的元素按照从小到大的顺序排列。
二、选择排序选择排序是一种简单但低效的排序算法,它的原理是每次从未排序的元素中选择最小的元素,然后与未排序部分的第一个元素交换位置,这样每一轮都能确定一个最小元素的位置。
具体实现时,我们可以使用两层循环来完成选择排序的过程。
外层循环控制比较的轮数,内层循环用于寻找未排序部分的最小元素并进行交换。
经过多轮比较和交换,最终数组中的元素按照从小到大的顺序排列。
三、插入排序插入排序是一种简单直观的排序算法,它的原理是将一个元素插入到已经排好序的数组中的合适位置。
具体实现时,我们可以使用两层循环来完成插入排序的过程。
外层循环控制待插入的元素,内层循环用于比较已排序部分的元素并进行移动。
经过多轮比较和移动,最终数组中的元素按照从小到大的顺序排列。
四、快速排序快速排序是一种高效的排序算法,它的原理是通过选择一个基准元素,将数组分成两部分,左边部分的元素都小于基准元素,右边部分的元素都大于基准元素,然后递归地对左右两部分进行排序。
具体实现时,我们可以使用递归函数来完成快速排序的过程。
在每一轮排序中,我们选择一个基准元素,将数组分成两部分,并对这两部分进行递归排序。
经过多轮递归排序,最终数组中的元素按照从小到大的顺序排列。
以上是常见的几种数组排序函数的原理和实现方式。
在实际编程中,我们可以根据具体的需求选择合适的排序算法。
c语言基础算法教学C语言是一门广泛应用于计算机编程的高级程序设计语言,也是学习其他计算机语言的基础。
在学习C语言的过程中,我们不可避免地会接触到各种基础算法。
本文将以C语言基础算法教学为主题,介绍一些常见的算法及其实现方法。
一、排序算法排序算法是计算机领域中最基础、最常用的算法之一。
常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序等。
下面我们以冒泡排序为例进行介绍。
冒泡排序的原理是重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就进行交换。
通过多次遍历,将最大(或最小)的元素逐渐交换到数列的末尾,从而实现排序。
下面是冒泡排序的C语言实现代码:```c#include <stdio.h>void bubbleSort(int array[], int n) {int i, j, temp;for (i = 0; i < n-1; i++) {for (j = 0; j < n-i-1; j++) {if (array[j] > array[j+1]) {temp = array[j];array[j] = array[j+1];array[j+1] = temp;}}}}int main() {int array[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(array)/sizeof(array[0]);bubbleSort(array, n);printf("排序后的数组:\n");for (int i = 0; i < n; i++) {printf("%d ", array[i]);}return 0;}```二、查找算法查找算法是在一组数据中寻找特定元素的算法。
常见的查找算法包括线性查找、二分查找、哈希查找等。
下面我们以二分查找为例进二分查找的前提是数据已经有序。
排序的方法,按照排序过程中结果序列生成的过程可以分为交换法、选择法和插入法。
冒泡排序:基本思想:首先制定排序规则,例如按照数据由大到小或由小到大的顺序,然后依稀两两比较待排序的数据,若不符合排序规则,则进行交换。
这样比较一遍之后,便有一个数据元素确定位置,然后依次比较下去,直到全部元素排列有序为止。
选择排序:基本思想:首先制定排序规则(例如按照从小到大排序原则),排序过程中首先在未排序序列中找到最小值,放在排序序列起始位置,随后,逐趟从余下未排序的数值中逐次寻找最小值,直到整个序列有序为止。
插入排序:基本思想:当插入第i 个元素的时候,前面i-1个元素已经排列好了,这时只需要用第i 个的关键字从最后开始与其他的进行比较,找到合适的位置,将后面的对象依次后移,然后将新的对象插入。
直接插入排序最大的优点就是具有合理性,也就是说,如果初始序列的情况较好,那么排序所需的移动比较次数就少,如果初始序列情况差,那么所需要的移动比较次数就多,因此直接插入排序适合那些基本上已经按顺序排列的序列。
Shell 排序:(缩小增量排序:diminishing increments )基本思想:设待排序的对象序列有n 个元素,首先取一个整数gap<n 作为间隔,将全部元素分为gap 个子序列,所有距离为gap 的元素属于同一个子序列,在每一个子序列中分别采用直接插入法,然后缩小gap ,直到gap=1,将所有对象放到同一个序列再排一次为止,其排序速度可以在一定程度上有所提高。
Gap 的取法:最初Shell 认为gap=n/2,然后依次取gap=gap/2,后来Knuth 提出gap=gap/3+1.还有人提出都去奇数比较好,总之,不同的研究者提出了不同的算法,但无论哪一种提法都没有得到证明。
快速排序:快速排序是冒泡排序的一种改进,由图灵奖获奖者、英国计算机系统大师霍尔(C.A.R Hoare )在1962年提出并演化而来的。
基本思想:通过一趟数据比较和交换,将要排序的数据分成前后两部分,其中一部分的数据比另外一部分的数据都要小,然后,再按照这种方法对分开的两部分数据分别进行一次快速排序,依次执行下去,直到整个序列有序为止。
例如,对无序序列011[]{,,...}n a n a a a -=,使用快速排序的过程为:首先,任选一个数据(通常选第一个元素数据0a )作为关键数据。
然后,将所有比它小的元素都交换到它前面,所有比它大的元素都交换到它后面,执行这样一次比较和交换的过程成为一趟快速排序。
一趟快速排序的算法描述如下:1) 设置两个变量low 和high ,排序初始时设置初始值为:low=0,high=n-1;2) 取第一个元素0a 作为关键数据,赋值给临时变量temp,即令temp=0a ;3) 从high 开始逐渐向序列前面搜索,即执行j —操作,依次与temp 比较,直到找到第一个小于temp 的元素位置,然后将找到的元素与temp 交换;4) 从low 开始向序列后面搜索,即执行i++操作,依次与temp 比较,直到找到第一个大于temp 的元素,然后将找到的元素与temp 交换;5) 重复上述3)、4)步,直到i=j 。
合并排序:合并排序又叫归并排序,合并排序的主要目的是将两个或多个有序的数组或链表等有序表合成一个新的有序表。
最简单的合并是将两个有序数组合并成一个有序数组。
典型的合并算法是2-路合并排序,即按照排序规则将两个位置相邻的有序表合并为一个有序表。
1.两个数组合并排序将两个有序数组Array1和Array2进行排序放到另一个数组ArrayMerge的基本思想为:首先,在Array 和Array2数组中各取第一个元素进行比较,将较小的元素放入数组ArrayMerge;然后,取较小元素所在数组的下一个元素与另一数组中上次比较后较大的元素比较,重复上述比较过程,直到某个数组先排序完;最后,将另一个数组中剩余元素连接到数组ArrayMerge中。
2.合并排序算法合并排序算法最常用的是2-路合并算法。
使用2-路合并排序算法,可以将无序序列排列成有序序列。
通常,可以采用递归形式的2-路合并排序方法。
其基本思想是将含有n个元素的待排序序列分为n个子序列,然后,两两进行合并,得到n/2或n/2+1个含有2个元素的子序列,将这些子序列再两两合并,直到生成一个长度为n的有序序列为止。
例如,有序列{ 85, 279, 948, 521, 616, 888, 0},将上述序列按照从小到大排列,使用合并排序算法的示意图如下图所示:Recursion2-路合并排序过程//从分治策略的机制入手,容易消除归并排序算法中的递归,事实上,递归算法MergeSort的递归过程只是将待排序列集合一分为二,直到待排序列集合只剩下一个元素为止,然后不断合并两个排好序的数组段。
按此机制,可以首先将数组a中相邻元素两两配对。
用合并算法将它们排序,构成n/2组长度为2的排好序的子数组段,然后再将它们排序成长度为4的排好序的子数组段,如此继续下去,直至整个数组排好序。
这就是自然合并排序的思想。
对于n元数组已排好顺序情况下,自然排序算法不执行合并,而递归算法MergeSort需执行[logn]次合并。
Iteration1)冒泡排序#include <stdio.h>#define N 5void BubbleSort(int a[], int n){int i=0,j=0,temp=0;printf("Start processing function BubbleSort()\n\n");for(i=0;i<n-1;i++){for (j=0;j<n-1-i;j++){if (a[j]>a[j+1]){temp = a[j];a[j] = a[j+1];a[j+1] = temp;}}}}void main(){int array[N],i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&array[i]);}printf("\n");BubbleSort(array,N);printf("The sorted array is:\n");for(i=0;i<N;i++){printf("%-5d",array[i]);}printf("\n");}2)选择排序#include <stdio.h>#define N 5void SelectSort(int a[], int n){int i=0, j=0, min=0, temp=0;printf("Start processing function SelectSort()\n\n");for(i=0;i<n-1;i++){min = i;for (j=i+1;j<n;j++){if (a[min]>a[j]){min = j;}}if (min!=i){temp = a[min];a[min] = a[i];a[i] = temp;}}}void main(){int array[N],i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&array[i]);}printf("\n");SelectSort(array,N);printf("The sorted array is:\n");for(i=0;i<N;i++){printf("%-5d",array[i]);}printf("\n");}#include <stdio.h>#define N 5void InsertSort(int a[], int n){int i=0,j=0,temp=0;printf("Start processing function InsertSort()\n\n");for(i=1;i<n;i++){temp = a[i];for (j=i-1;j>=0;j--){if (a[j]>temp){a[j+1] = a[j];//a[j] = temp;}else{break;}}a[j+1] = temp; // 任选其一}}void main(){int array[N],i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&array[i]);}printf("\n");InsertSort(array,N);printf("The sorted array is:\n");for(i=0;i<N;i++){printf("%-5d",array[i]);}printf("\n");}#include <stdio.h>#define N 5void ShellSort(int a[], int n){int i=0,j=0,temp=0;int gap = 0;printf("Start processing function ShellSort()\n");for (gap=n/2;gap>0;gap/=2){for(i=gap;i<n;i++){temp = a[i];for (j=i-gap;j>=0;j=j-gap){if (a[j]>temp)a[j+gap] = a[j];elsebreak;}a[j+gap] = temp;}}}void main(){int array[N],i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&array[i]);}printf("\n");ShellSort(array,N);printf("The sorted array is:\n");for(i=0;i<N;i++){printf("%-5d",array[i]);}printf("\n");}// a[]={13,18,17,2,15,4,19}#include <stdio.h>#define N 7int partition(int data[], int low, int high){int temp;temp = data[low];while (low<high){while ( (data[high]>temp) && (low<high) ){high--;}data[low] = data[high];while ( (data[low]<temp) && (low<high) ){low++;}data[high] = data[low];}data[low] = temp;return low;}void FastSort(int data[], int low, int high){int mid;if (low<high) // 注意此条件{mid = partition(data,low,high);FastSort(data,low,mid-1);FastSort(data,mid+1,high);}}void main(void){int a[N];int i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&a[i]);}FastSort(a,0,N-1);printf("The sorted array is:\n");for (i=0;i<N;i++){printf("%-5d",a[i]);}printf("\n");}6) 合并(归并)排序:递归// a[]={13,18,17,2,15,4,19}// a[]={34 23 12 55 66 4 2 99 1 45 77 88 99 5}#include <stdio.h>#define N 14void ArrayMerge(int data[], int low, int mid, int high){static int copy_data[N];int i=low, j=mid+1, k=0;int ind;while (i<=mid&&j<=high)copy_data[k++] = (data[i]<data[j])?data[i++]:data[j++];if (i>mid){while(j<=high)copy_data[k++] = data[j++];}else{while (i<=mid)copy_data[k++] = data[i++];}for (ind=0;ind<k;ind++)data[ind+low] = copy_data[ind];}void MergeSort(int data[], int low, int high){int mid=0;if (low<high) // 注意此条件{mid = (low+high)/2;MergeSort(data,low,mid);MergeSort(data,mid+1,high);ArrayMerge(data,low,mid,high);}}void main(void){int a[N];int i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&a[i]);}MergeSort(a,0,N-1);printf("The sorted array is:\n");for (i=0;i<N;i++){printf("%-5d",a[i]);}printf("\n");}7) 合并(归并)排序:迭代// a[]={13,18,17,2,15,4,19}// a[]={34 23 12 55 66 4 2 99 1 45 77 88 99 5}#include <stdio.h>#define N 7void ArrayMerge(int data[],int low, int mid, int high){int copy_data[N];int i=low, j=mid+1, k=0, ind=0;while ((i<=mid) && (j<=high))copy_data[k++] = (data[i]<data[j])?data[i++]:data[j++];if (i>mid){while (j<=high)copy_data[k++] = data[j++];}else{while (i<=mid)copy_data[k++] = data[i++];}for (ind=0;ind<k;ind++)data[low+ind] = copy_data[ind]; }void MergePass(int data[],int s){int i=0;for (i=0;i<=N-2*s;i=i+2*s)ArrayMerge(data, i, i+s-1, i+2*s-1);if (N-i>s) // (N-1)-i+1>sArrayMerge(data, i, i+s-1, N-1);}void MergeSort(int data[]){int s = 1;while (s<N){MergePass(data,s);s=2*s;}}void main(void){int a[N];int i;printf("Please enter %d integers:\n",N);for (i=0;i<N;i++){scanf("%d",&a[i]);}MergeSort(a);printf("The sorted array is:\n");for (i=0;i<N;i++){printf("%-5d",a[i]);}printf("\n");}。