快排算法quickSort
来源:互联网 发布:jackson json 官网 编辑:程序博客网 时间:2024/03/29 03:51
感觉在网上查找到的有关quickSort的资料都不是很详细或简洁,特把自己的理解做个总结,记录,以待分享。
1、时间复杂度及推导思想:
快排的平均时间复杂度为O(nlog(n)),最差为O(n*n)。
其时间复杂度的推到可利用二叉树的思想:切分的次数是树高n,查找的次数为logn,总的时间复杂度为nlog(n)。
数学推导思想:首先我们请注意到,所有实际的排序操作都在partition中做完的,因为排序从根本上来讲还是元素的交换,那么在partition函数中进行了多少次比较就是整个算法复杂度的关键。
如果将A中的元素排列成S (z1,z2,…,zn),zi表示第i小元素。在整个排序过程中,任意两个元素最多比较一次。如果我们定义一个变量Xij,当zi和zj发生比较时为1,否则为0。那么
把对所有可ij求和Xij就得到全部的比较次数。我们对这个和求期望,根据期望的线性性,也就是zi和zj发生比较的概率的总和。
那么zi和zj发生比较的概率是多少呢?在Sij这个子集合里,只有zi或zj被选为pivot的时候他们才会有比较,而平均来讲,这个概率是2/(j-i+1)。这就是S中任意两个元素发生比较的概
率。如果不在这个集合里呢?
因此所有比较次数的表达式是Sum(2/(j-i+1)), i从1到n-1,j从i+1到n。
他可以变形为n个Sum(2/k)k从1到n。
最终得到n*lg(n)。
2、实现的原理及思路
快排的整体思想是随机挑选一个元素,对数组进行分割,以将所有比它小的元素排在前面,比它大的元素排在后面。分割反复执行,直到有序。
1)给定一个数组arr[ ],定义数组首元素的索引和尾元素的索引分别为left和right。
2)以中间位置arr[(left+right)/2]为基准点pivot。
3)从左面第一个元素开始向右搜索,即由左向右(left++),找到第一个大于pivot的值arr[left],则停止,与同样停止的arr[right]进行交换,swap(arr,left,right)。
4)从右面第一个元素开始向左搜索,即由右向左(right--),找到第一个小于pivot的值arr[right],则停止,与同样停止的arr[left]进行交换,swap(arr,left,right)。
5)重复3)、4)步操作,直到满足left==right,这时arr[left]=arr[right]=pivot,而pivot的位置就是在数组中的正确位置。
6)递归调用,对pivot的左右部分分别进行2)~ 5)的操作,最后解出问题。
核心思想代码:
void quickSort(int arr[],int left, int right){ int index = partition(arr, left, right); if (left < index-1){//对左半部分进行切分,递归排序 quickSort(arr, left, index-1); } if (right > index){//对右半部分进行切分,递归排序 quickSort(arr, index, right); } } int partition(int arr[],int left, int right){ int pivot = arr[(left+right)/2];//选取一个基准点 while(left <= right){ while (arr[left] < pivot) left++;//指针从左面开始向基准点移动,直到不满足条件停止 while (arr[right] > pivot) right--;//指针从右面开始向基准点移动,直到不满足条件停止 //对停止的左右两个元素进行换位,调整左右索引值,然后继续循环 if(left <= right){ swap(arr, left, right); left++; right--; } } return left;//返回的位置满足arr[left]=arr[right]=pivot } void swap(int arr[],int left,int right){ int temp; temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; }
java可测试执行代码:
package com.company;/** * Created by zu on 14-10-4. */public class QuickSortTest { public static void quickSort(int arr[],int left, int right){ int index = partition(arr, left, right); if (left < index-1){//对左半部分进行切分,递归排序 quickSort(arr, left, index-1); } if (right > index){//对右半部分进行切分,递归排序 quickSort(arr, index, right); } } public static int partition(int arr[],int left, int right){ int pivot = arr[(left+right)/2];//选取一个基准点 while(left <= right){ while (arr[left] < pivot) left++;//指针从左面开始向基准点移动,直到不满足条件停止 while (arr[right] > pivot) right--;//指针从右面开始向基准点移动,直到不满足条件停止 //对停止的左右两个元素进行换位,调整左右索引值,然后继续循环 if(left <= right){ swap(arr, left, right); left++; right--; } } return left;//返回的位置满足arr[left]=arr[right]=pivot } public static void swap(int arr[],int left,int right){ int temp; temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; } //打印数组 public static void print(int arry[]) { for(int i:arry) { System.out.print(i+" "); } System.out.println(); } public static void main(String args[]){ int arr[] = {1,43,5454,33,4,33,6,66,23,22,45,2,3,35}; int len = arr.length; System.out.print("快速排序前数组元素为:"); print(arr); quickSort(arr,0,len-1); System.out.print("快速排序后数组元素为:"); print(arr); }}执行结果输出:
快速排序前数组元素为:1 43 5454 33 4 33 6 66 23 22 45 2 3 35 快速排序后数组元素为:1 2 3 4 6 22 23 33 33 35 43 45 66 5454
- 快排算法quickSort
- QuickSort 快排算法 java
- QuickSort(经典快排算法)
- java快速排序(快排)算法Quicksort
- 快排 quicksort
- 快排QuickSort
- 快排QuickSort
- lua的快排(QuickSort)
- QuickSort/快速排序/快排
- 可执行的快排 quicksort
- python 版 quicksort 快排
- QuickSort快排详细解释
- C语言递归实现快排quicksort
- 算法----快排算法
- 快排算法
- 快排算法
- 快排算法
- 快排算法cmp
- ORACLE之常用FAQ V1.0,已经停止更新
- 转 Python 2.7 学习摘记
- 校招9月份找工作的童鞋进
- 数据统计的错误分析与改进
- 使用SiteScope监控WebLogic
- 快排算法quickSort
- OC 弱引用 weak __weak assign __assign
- HDU_ACM-2057 A+B again
- HDU1007Quoit Design(最小点对)
- Unity3D NGUI事件 UIEvents
- Java简述
- HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议
- OC 的13个缺点
- 【Stanford Machine Learning】Lecture 2--Linear Regression with Multiple Variables