首页 > 代码库 > 经典排序算法
经典排序算法
1.冒泡排序法
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。
由于冒泡排序简洁的特点,它通常被用来对于计算机程序设计入门的学生介绍算法的概念。
冒泡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"); }
2.直接插入排序法
插入排序法就是检查第i个数字,如果在它的左边的数字比它大,进行交换,这个动作一直继续下去,直到这个数字的左边数字比它还要小,就可以停止了。插入排序法主要的回圈有两个变数:i和j,每一次执行这个回圈,就会将第i个数字放到左边恰当的位置去。
每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
#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; }
3.直接选择排序算法
直接选择排序(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次,得到一个按排序码从小到大排列的有序序列·
#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]); } */
4.快速排序算法
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
#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]); }
5.归并排序算法
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。值得注意的是归并排序是一种稳定的排序方法。
归并操作(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; }
后面两个还没看懂 特别是最后一个。。。