排序算法 1,冒泡排序 原文链接(http://www.cnblogs.com/kkun/archive/2011/11/23/2260280.html)
经典排序算法 - 冒泡排序Bubble sort 原理是临近的数字两两进行比较,按照从小到大或者从大到小的顺序进行交换, 这样一趟过去后,最大或最小的数字被交换到了最后一位, 然后再从头开始进行两两比较交换,直到倒数第二位时结束,其余类似看例子 例子为从小到大排序, 原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |
第一趟排序(外循环) 第一次两两比较6 > 2交换(内循环) 交换前状态| 6 | 2 | 4 | 1 | 5 | 9 | 交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |
第二次两两比较,6 > 4交换 交换前状态| 2 | 6 | 4 | 1 | 5 | 9 | 交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |
第三次两两比较,6 > 1交换 交换前状态| 2 | 4 | 6 | 1 | 5 | 9 | 交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |
第四次两两比较,6 > 5交换 交换前状态| 2 | 4 | 1 | 6 | 5 | 9 | 交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第五次两两比较,6 < 9不交换 交换前状态| 2 | 4 | 1 | 5 | 6 | 9 | 交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第二趟排序(外循环) 第一次两两比较2 < 4不交换 交换前状态| 2 | 4 | 1 | 5 | 6 | 9 | 交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |
第二次两两比较,4 > 1交换 交换前状态| 2 | 4 | 1 | 5 | 6 | 9 | 交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换 交换前状态| 2 | 1 | 4 | 5 | 6 | 9 | 交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第四次两两比较,5 < 6不交换 交换前状态| 2 | 1 | 4 | 5 | 6 | 9 | 交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |
第三趟排序(外循环) 第一次两两比较2 > 1交换 交换后状态| 2 | 1 | 4 | 5 | 6 | 9 | 交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第二次两两比较,2 < 4不交换 交换后状态| 1 | 2 | 4 | 5 | 6 | 9 | 交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第三次两两比较,4 < 5不交换 交换后状态| 1 | 2 | 4 | 5 | 6 | 9 | 交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |
第四趟排序(外循环)无交换 第五趟排序(外循环)无交换
排序完毕,输出最终结果1 2 4 5 6 9
C语言代码
#include <iostream>using namespace std;// 冒泡排序extern void swap( int *a, int *b);int main(int argc, char* argv[]){ int arr[10] = { 8,5,2,1,3,7,6,9,0,4 }; for( int i = 0; i < 10; i ++ ) { for( int j = i+1; j < 10; j ++ ) { if( arr[i] > arr[j] ) { swap( &arr[i], &arr[j] ); } } } { cout << "冒泡排序结果" << endl; for( int i = 0; i < 10; i ++ ) { cout << arr[i] << " "; } cout << endl; } return 0;}void swap(int *a, int *b) { int c; c = *a; *a = *b; *b = c; }2,选择排序 原文链接(http://www.cnblogs.com/luchen927/archive/2012/02/27/2367108.html) 选择排序的思想。从所有序列中先找到最小的,然后放到第一个位置。之后再看剩余元素中最小的,放到第二个位置……以此类推,就可以完成整个的排序工作了。可以很清楚的发现,选择排序是固定位置,找元素。相比于插入排序的固定元素找位置,是两种思维方式。不过条条大路通罗马,两者的目的是一样的。
C语言代码
3,快速排序 原文链接(百度百科:快速排序) 快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
1算法介绍 设要排序的数组是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-完成的时候,此时令循环结束)。
2排序演示 假设用户输入了如下数组: 下标 0 1 2 3 4 5 数据 6 2 7 3 8 9 创建变量i=0(指向第一个数据), j=5(指向最后一个数据), k=6(赋值为第一个数据的值)。 我们要把所有比k小的数移动到k的左面,所以我们可以开始寻找比6小的数,从j开始,从右往左找,不断递减变量j的值,我们找到第一个下标3的数据比6小,于是把数据3移到下标0的位置,把下标0的数据6移到下标3,完成第一次比较: 下标 0 1 2 3 4 5 数据 3 2 7 6 8 9 i=0 j=3 k=6 接着,开始第二次比较,这次要变成找比k大的了,而且要从前往后找了。递加变量i,发现下标2的数据是第一个比k大的,于是用下标2的数据7和j指向的下标3的数据的6做交换,数据状态变成下表: 下标 0 1 2 3 4 5 数据 3 2 6 7 8 9 i=2 j=3 k=6 称上面两次比较为一个循环。 接着,再递减变量j,不断重复进行上面的循环比较。 在本例中,我们进行一次循环,就发现i和j“碰头”了:他们都指向了下标2。于是,第一遍比较结束。得到结果如下,凡是k(=6)左边的数都比它小,凡是k右边的数都比它大: 下标 0 1 2 3 4 5 数据 3 2 6 7 8 9 如果i和j没有碰头的话,就递加i找大的,还没有,就再递减j找小的,如此反复,不断循环。注意判断和寻找是同时进行的。 然后,对k两边的数据,再分组分别进行上述的过程,直到不能再分组为止。 注意:第一遍快速排序不会直接得到最终结果,只会把比k大和比k小的数分到k的两边。为了得到最后结果,需要再次对下标2两边的数组分别执行此步骤,然后再分解数组,直到数组不能再分解为止(只有一个数据),才能得到正确结果。 C语言代码 // 快速排序
// 快速排序#include "stdafx.h"#include <stdio.h>#include <stdlib.h> const int MAX_ELEMENTS = 10;extern void PRintlist(int list[],int n);extern void swap(int *x,int *y);extern int choose_pivot(int i,int j );extern void quicksort(int list[],int m,int n);void main(){ int list[10] = { 8,5,2,1,3,7,6,9,0,4 }; printf("快速排序前:/n"); printlist(list,MAX_ELEMENTS); // sort the list using quicksort quicksort(list,0,MAX_ELEMENTS-1); // print the result printf("快速排序后:/n"); printlist(list,MAX_ELEMENTS);}void printlist(int list[],int n){ int i; for(i=0;i<n;i++) printf("%d/t",list[i]);}void swap(int *x,int *y){ int temp; temp = *x; *x = *y; *y = temp;}int choose_pivot(int i,int j ){ return((i+j) /2);}void quicksort(int list[],int m,int n){ printlist(list,MAX_ELEMENTS); int key,i,j,k; if( m < n) { k = choose_pivot(m,n); swap(&list[m],&list[k]); key = list[m]; i = m+1; j = n; while(i <= j) { while((i <= n) && (list[i] <= key)) i++; while((j >= m) && (list[j] > key)) j--; if( i < j) swap(&list[i],&list[j]); } swap(&list[m],&list[j]); quicksort(list,m,j-1); quicksort(list,j+1,n); }}4,归并排序 原文链接(百度百科:归并排序) 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。
C语言代码
//// 归并排序#include "stdafx.h"#include<iostream> using namespace std; #include "stdio.h"#include "stdlib.h"const int MAX_ELEMENTS = 10;//第一个参数为需要排序的数组,第2个参数为分割的第一个数组开始元素的下标 //第3个参数为分割的第一个数组的最后1个元素的下标 //第4个参数为数组最后1个元素的下标 extern void Merge(int *A,int p,int q,int r); extern void MergeSort(int *A,int p,int r);extern void printlist(int list[],int n);void main() { int list[MAX_ELEMENTS] = { 8,5,2,1,3,7,6,9,0,4 }; cout << "归并排序前" << endl; printlist(list,MAX_ELEMENTS); MergeSort( list, 0, MAX_ELEMENTS-1 ); cout << "归并排序后" << endl; printlist(list,MAX_ELEMENTS); system("pause"); } void Merge(int *A,int p,int q,int r) { int n1,n2,i,j,k,g; n1=q-p+1; n2=r-q; int *L,*R; L=(int *)malloc(sizeof(int)*(n1+1)); R=(int *)malloc(sizeof(int)*(n2+1)); L[n1]=0x7fff; //开辟的左右2个数组最后1个数设置为最大值 R[n2]=0x7fff; g=0; for(i=p;i<=q;i++) { L[g]=A[i]; g++; } g=0; for(i=q+1;i<=r;i++) { R[g]=A[i]; g++; } //逐个比较左右两组数组,把较小的值写入原来的数组 j=k=0; for(i=p;i<=r;i++) { if(L[j]<R[k]) { A[i]=L[j]; j++; } else { A[i]=R[k]; k++; } } } void MergeSort(int *A,int p,int r) { int q; if(p<r) //当第一个元素比最后1个元素还小时,继续执行递归,直到只剩下一个元素(形参p=r) { q=(p+r)/2; MergeSort(A,p,q); MergeSort(A,q+1,r); Merge(A,p,q,r); } } void printlist(int list[],int n){ int i; for(i=0;i<n;i++) printf("%d/t",list[i]);}新闻热点
疑难解答