标签:
快速排序最坏情况运行时间为O(n2),但实际中通常都是用于排序的最佳的实用选择,因为其平均性能相当好:期望的运行时间为O(nlgn),且O(nlgn)记号中隐含的常数因子很小。
快速排序是一种就地排序。同时,是一种不稳定的排序。本文内容主要参照算法导论。
快速排序主要利用了分治的思想。一般分为三步进行:
分解:数组A[p..r]被划分为两个子数组A[p..q-1]和A[q+1..r],其中A[p..q-1]的元素都小于等于A[q],A[q+1..r]都大于等于A[q]。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1..r]排序。
合并:因为两个子数组是就地排序的,将它们合并不需要额外操作,整个数组已经是排好序的。
下面是快速排序的C语言代码:
1 int QuickSort(int *A,int p, int r) 2 { 3 if(p<r) 4 { 5 int q; 6 q=Partition(A,p,r); 7 QuickSort(A,p,q-1); 8 QuickSort(A,q+1,r); 9 } 10 }
快速排序的关键是Partition过程,它对子数组A[p..r]进行就地排序,代码如下:
1 int Partition(int *A,int p, int r) 2 { 3 int i,j,x; 4 x=A[p]; //选取第一个元素作为主元 5 i=p; 6 for(j=p;j<r;j++) 7 { 8 if(x>=A[j+1]) //若小于等于主元则交换元素j+1和i+1 9 { 10 int temp; 11 temp=A[i+1]; 12 A[i+1]=A[j+1]; 13 A[j+1]=temp; 14 i++; 15 } 16 } 17 int temp; //最后一步,将主元放到合适的位置,因为此处选取的主元的第一个元素,而i所指向的是最后一个小于等于主元的元素,因此交换主元和i元素,
使得A[p..q-1]的元素都小于等于A[q],A[q+1..r]都大于等于A[q] 18 temp=A[p]; 19 A[p]=A[i]; 20 A[i]=temp; 21 return i; 22 }
下图左边描述了快排的Partition过程,图中主元选取的是最后一个元素跟上述代码不一样,不过这没关系。右边是快速排序的动态演示。
始终记住,i是小于和大于主元的分界线,二j是已处理和未处理的分界线,即i前面的元素都是小于等于主元,而i+1到j都是大于等于主元的元素,j之后的元素是还没比较的元素。
最后,贴上我在devc++里写的完整代码:
1 #include <iostream> 2 #include <stdlib.h> 3 using namespace std; 4 5 int QuickSort(int *A,int p, int r); 6 int Partition(int *A,int p, int r); 7 8 int main() 9 { 10 int i,n; 11 cout<<"Please input the size of your array"<<endl; 12 cin>>n; 13 int *A = new int[n]; 14 cout<<"Please input your array"<<endl; 15 for(i=0;i<n;i++) 16 { 17 cin>>A[i]; 18 } 19 QuickSort(A,0,n-1); 20 for(i=0;i<n;i++) 21 { 22 cout<<A[i]<<" "; 23 24 } 25 cout<<endl; 26 delete A; 27 system("pause"); 28 return 0; 29 } 30 31 int QuickSort(int *A,int p, int r) 32 { 33 if(p<r) 34 { 35 int q; 36 q=Partition(A,p,r); 37 QuickSort(A,p,q-1); 38 QuickSort(A,q+1,r); 39 } 40 } 41 42 int Partition(int *A,int p, int r) 43 { 44 int i,j,x; 45 x=A[p]; 46 i=p; 47 for(j=p;j<r;j++) 48 { 49 if(x>A[j+1]) 50 { 51 int temp; 52 temp=A[i+1]; 53 A[i+1]=A[j+1]; 54 A[j+1]=temp; 55 i++; 56 } 57 } 58 int temp; 59 temp=A[p]; 60 A[p]=A[i]; 61 A[i]=temp; 62 return i; 63 }
另外,快排还有一种典型的实现方法,就是霍尔快排,维基百科上介绍的快速排序就是这种实现。下面贴上维基百科的霍尔快排:
1 void swap(int *x, int *y) { 2 int t = *x; 3 *x = *y; 4 *y = t; 5 } 6 void quick_sort_recursive(int arr[], int start, int end) { 7 if (start >= end) 8 return;//這是為了防止宣告堆疊陣列時當機 9 int mid = arr[end]; 10 int left = start, right = end - 1; 11 while (left < right) { 12 while (arr[left] < mid && left < right) 13 left++; 14 while (arr[right] >= mid && left < right) 15 right--; 16 swap(&arr[left], &arr[right]); 17 } 18 if (arr[left] >= arr[end]) 19 swap(&arr[left], &arr[end]); 20 else 21 left++; 22 quick_sort_recursive(arr, start, left - 1); 23 quick_sort_recursive(arr, left + 1, end); 24 } 25 void quick_sort(int arr[], int len) { 26 quick_sort_recursive(arr, 0, len - 1); 27 }
标签:
原文地址:http://www.cnblogs.com/danieldachao/p/5722095.html