它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。
由于冒泡排序简洁的特点,它通常被用来对于计算机程序设计入门的学生介绍算法的概念。
冒泡C语言代码
#include<stdio.h> #define SIZE 8 void bubble_sort(int a[],int n)//n为数组a的元素个数 { int i,j,temp; for(j=0;j<n-1;j++) for(i=0;i<n-1-j;i++) { if(a[i]>a[i+1])//数组元素大小按升序排列 { temp=a[i]; a[i]=a[i+1]; a[i+1]=temp; } } } int main() { int number[SIZE]={95,45,15,78,84,51,24,12}; int i; bubble_sort(number,SIZE); for(i=0;i<SIZE;i++) { printf("%d",number[i]); } printf("\n"); }
插入排序法就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。插入排序法主要的回圈有两个变数:i和j,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中;依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。 直接插入排序属于稳定的排序,最坏时间复杂性为O(n^2),空间复杂度为O(1)。 直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。 值得注意的是,我们必需用一个存储空间来保存当前待比较的数值,因为当一趟比较完成时,我们要将待比较数值置入比它小的数值的后一位 插入排序类似玩牌时整理手中纸牌的过程。插入排序的基本方法是:每步将一个待排序的记录按其关键字的大小插到前面已经排序的序列中的适当位置,直到全部记录插入完毕为止。#include<stdio.h> int main() { int a[]={98,76,109,34,67,190,80,12,14,89,1}; int k=sizeof(a)/sizeof(a[0]);//使用 sizeof把a所有的内存大小读出 int i,j; //sizeof(a[0])把a中一个元素的大小, //在用总的除以一个的得到长度。 for(i=2;i<k;i++)//循环从第3个元素开始 { if(a[i]<a[i-1]) //后面一个小于前面一个 { int temp=a[i]; //将a[i]的值赋给temp for(j=i-1;j>=0&&a[j]>temp;j--) //嵌套循环 从i-1,直到a[j]大于temp a[j+1]=a[j]; //把a[i]与a[i-1]交换 a[j+1]=temp; //循环完将temp移动到有序处 } } for(i=0;i<k;i++) { printf("%d ",a[i]); } return 0; }
直接选择排序(Straight Select Sorting) 也是一种简单的排序方法,它的基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,....,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列·
例如:给定n=8,数组R中的8个元素的排序码为(8,3,2,1,7,4,6,5),则直接选择排序的过程如下所示 由于百科不方便画出关联箭头 所以用 n -- n 表示 : 初始状态 [ 8 3 2 1 7 4 6 5 ] 8 -- 1 第一次 [ 1 3 2 8 7 4 6 5 ] 3 -- 2 第二次 [ 1 2 3 8 7 4 6 5 ] 3 -- 3 第三次 [ 1 2 3 8 7 4 6 5 ] 8 -- 4 第四次 [ 1 2 3 4 7 8 6 5 ] 7 -- 5 第五次 [ 1 2 3 4 5 8 6 7 ] 8 -- 6 第六次 [ 1 2 3 4 5 6 8 7 ] 8 -- 7 第七次 [ 1 2 3 4 5 6 7 8 ] 排序完成#include<stdio.h> void SelectSort(int R[], int n)//类型int可以改为其他类型。n为数组长度 { int i,j,m; int t; for(i=0;i<n-1;i++) //循环n-1次 { m = i; for(j=i+1; j<n; j++)//嵌套循环 每次循环把i后面的最小数返回给i { if(R[j]<R[m]) m=j; } if(m!=i) //m改变则改变数组的值 { t=R[i]; R[i]=R[m]; R[m]=t; } } } /* 以下为演示算法 main() { int a[8]={8,3,2,1,7,4,6,5},i; SelectSort(a,8); for(i=0;i<8;i++) printf("%d ",a[i]); } */
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。 一趟快速排序的算法是: 1)设置两个变量i、j,排序开始的时候:i=0,j=N-1; 2)以第一个数组元素作为关键数据,赋值给key,即key=A[0]; 3)从j开始向前搜索,即由后开始向前搜索(j--),找到第一个小于key的值A[j],将A[j]赋给A[i]; 4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key的A[i],将A[i]赋给A[j]; 5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key,4中A[i]不大于key的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)#include<stdio.h> void QuickSort(int a[],int numsize)//a是整形数组,numsize是元素个数 { int i=0,j=numsize-1,t; int val=a[0];//指定参考值val大小 if(numsize>1)//确保数组长度至少为2,否则无需排序 { while(i<j)//循环结束条件(i==j) { for(;j>i;j--)//从后向前搜索比val小的元素,找到后填到a[i]中并跳出循环 {printf("垃圾1 "); if(a[j]<val) { printf("垃圾3 "); a[i]=a[j]; for(t=0;t<numsize;t++) printf("%d ",a[t]); printf("\n"); break; }} for(;i<j;i++)//从前往后搜索比val大的元素,找到后填到a[j]中并跳出循环 {printf("垃圾2 "); if(a[i]>val) {printf("垃圾4 "); a[j]=a[i]; for(t=0;t<numsize;t++) printf("%d ",a[t]); printf("\n"); break; } } } a[i]=val;//将保存在val中的数放到a[i]中 QuickSort(a,i);//递归,对前i个数排序 QuickSort(a+i+1,numsize-1-i);//对i+1到numsize这numsize-1-i个数排序 } } main() { int a[8]={8,5,7,6,2,4,1,3},n=8,i; QuickSort(a,n); for(i=0;i<n;i++) printf("%d ",a[i]); }
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
#include<stdio.h> void Merge(int sourceArr[],int targetArr[],int startIndex,int midIndex,int endIndex) { int i,j,k; for(i=midIndex+1,j=startIndex;startIndex<=midIndex&&i<=endIndex;j++) { if(sourceArr[startIndex]<sourceArr[i]) { targetArr[j]=sourceArr[startIndex++]; } else { targetArr[j]=sourceArr[i++]; } } if(startIndex<=midIndex) { for(k=0;k<=midIndex-startIndex;k++) { targetArr[j+k]=sourceArr[startIndex+k]; } } if(i<=endIndex) { for(k=0;k<=endIndex-i;k++) { targetArr[j+k]=sourceArr[i+k]; } } } //内部使用递归,空间复杂度为n+logn void MergeSort(int sourceArr[],int targetArr[],int startIndex,int endIndex) { int midIndex; int tempArr[100];//此处大小依需求更改 if(startIndex==endIndex) { targetArr[startIndex]=sourceArr[startIndex]; } else { midIndex=(startIndex+endIndex)/2; MergeSort(sourceArr,tempArr,startIndex,midIndex); MergeSort(sourceArr,tempArr,midIndex+1,endIndex); Merge(tempArr,targetArr,startIndex,midIndex,endIndex); } } //调用 int main(int argc,char *argv[]) { int a[8]={50,10,20,30,70,40,80,60}; int b[8],i; MergeSort(a,b,0,7); for(i=0;i<sizeof(a)/sizeof(*a);i++) printf("%d ",b[i]); printf("\n"); system("pause"); return 0; }
后面两个还没看懂 特别是最后一个。。。