快速排序
来源:互联网 发布:淘宝取店名 编辑:程序博客网 时间:2024/06/06 16:36
快速排序:
基本原理:快速排序也是基于分治模式的。
分治过程的三个步骤:
分解:数组A[p...r]被划分成两个(可能空)子数组A[p..q-1]和A[q+1...r],使得A[p..q-1]中的每个元素都小于等于A(q),而且,小于等于A[q+1..r]中的元素。下标q也在这个划分过程中进行计算。
解决:通过递归调用快速排序,对子数组A[p..q-1]和A[q+1...r]排序。
合并:因为两个子数组是就地排序的,将它们的合并不需要操作:整个数组A[p...r]已排序。
平均运行时间:O(nlgn),最坏情况运行时间为O(n^2)。
以上摘自《算法导论》
一个版本代码实现:
#include<stdio.h>#define N 50 int A[N] ;int Partition(/*int *A*/int p,int r) ;void QuickSort(/*int *A*/int p,int r) ;int main(void){int i,n ;freopen("in.txt","r",stdin) ;while(scanf("%d",&n) != EOF){for(i = 0 ; i < n ; ++i){scanf("%d",&A[i]) ;}printf("You had input the List:\n") ; for(i = 0 ; i < n ; ++i){printf("%-3d",A[i]) ;}printf("\n") ;QuickSort(/*A*/0,n-1) ;printf("After Sort:\n") ;for(i = 0 ; i < n ; ++i){printf("%-3d",A[i]) ;}printf("\n\n") ;}return 0 ;}int Partition(/*int *A*/int p,int r) {int x = A[r] ;int i,j,nTemp ;i = p - 1 ;for(j = p ; j < r ; ++j){if(A[j] <= x){i++ ; nTemp = A[i] ;A[i] = A[j] ; A[j] = nTemp ; }}nTemp = A[i+1] ;A[i+1] = A[r] ;A[r] = nTemp ;return i+1 ;}void QuickSort(/*int *A*/int p,int r) {int q = 0 ;if(p < r){q = Partition(p,r) ;QuickSort(p,q-1) ;QuickSort(q+1,r) ;}}
这个版本对于我来说比较好理解,特别是Partition这个函数。它将数组分为4个区间,一个是元素比主元小的区间,一个是元素比主元大的区间,一个是元素未进行与主元比较的区间,一个是主元区间。(《算法导论》有图解,更清晰)
Partition这个函数其实很好用,今天在其它地方看到两个面试题,其中一个大概就是:对一个包含正负数的数组进行处理,处理完毕之后要求全部负数在全部正数左边。时间复杂度要求O(n),空间复杂度O(1)。
思路:其实就是对0的Partition。不过,也有其它方法,之前写过,就不再提了。
另外一个面试题就是包含奇偶数的,也是要进行分开。其实也是一样的道理。
下面附上另外一个快速排序的版本,自己压根没理解:
void qsort(int lt,int rt){ int i,j,mid,t; i = lt; j = rt; mid = a[ (lt + rt) / 2 ]; do { while (a[i] < mid && i<rt) ++i; while (a[j] > mid && j>lt) --j; if (i<=j) { t = a[i];a[i] = a[j];a[j] = t; ++i;--j; } }while (i<=j); if (i<rt) qsort(i,rt); if (j>lt) qsort(lt,j);}
- 快速排序
- 快速排序
- 快速排序
- 快速排序!
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 快速排序
- 自己写的mysql客户端应用程序(通过官方头文件和lib来编译链接实现)
- 4.5. 调试系统故障
- AVI movi LIST
- 堆排序
- Head Fisrt Android Development读书笔记(1)Adding Behavior
- 快速排序
- 深入学习javascript
- 【菜鸟C++学习笔记】20.常指针&指向常量的指针&指向常量的常指针
- MDK中变量全局地址和局部变量地址重合问题--fyyy
- 【专家专栏】Android中的防缓冲区溢出技术
- 《数据结构与算法C#语言描述》笔记目录
- 快速求斐波那契数(scheme实现)
- 计算字符串的相似度--编程之美3.3
- 开发者反思诺基亚衰退:过早判Symbian死刑是大错