内部排序04——快速排序
原理:1.选取中枢元素
2.i从左向右扫描,如果小于中枢,则自增,否则记为a[i]
3.j从右向左扫描,如果大于中枢,自减,否则记为a[j]
4.交换a[i]和a[j]
5.重复直到ij交错,之后和基准元素比较,之后交换
复杂度:最好O(nlogn)
最坏:n^2/2
速度比归并排序要快
采用分治解法来求解,就地排序,非稳定。在编程语言中对数组、列表的排序,一般用快排。
Java实现
public void sortColors(int[] nums) {
//快排就是找start, end,然后确定枢纽,之后比较,换
quickSort(nums,0,nums.length-1);
}
public void quickSort(int[] nums, int start,int end){
if(start == end) return;
if(start < end){
int index = patition(nums, start, end); //找到分区
quickSort(nums,start,index-1);
quickSort(nums,index+1,end);
}
}
public int patition(int[] nums, int start,int end){
if(start == end) return start;
int index= nums[start]; //选第一个元素作为判断枢纽
while (start < end){
//先从后往前找第一个小于枢纽的值
while (start < end && nums[end] > index){
end--;
}
nums[start] = nums[end];
//找到前半段,第一个大于枢纽的值
while (start < end && nums[start] <= index){
start++;
}
nums[end] = nums[start];
}
//start==end的时候,就表示本轮ok,把枢纽放到end或者start,作为新的枢纽
// 因为枢纽选的是start,所以 index start end ,
// nums[end]放到了start,nums[start]放到了end,那么start或者end退出时的值为空啊,所以就放index
nums[end] = index;
return end;
}
public static void main(String[] args) {
int[] nums = {2,0,2,1,1,0};
new L75_Sort_Colors().sortColors(nums);
Utils.printArr(nums);
}
/**********************************************************
名称:快速排序
原理:
1.选取中枢元素
2.i从左向右扫描,如果小于中枢,则自增,否则记为a[i]
3.j从右向左扫描,如果大于中枢,自减,否则记为a[j]
4.交换a[i]和a[j]
5.重复直到ij交错,之后和基准元素比较,之后交换
***********************************************************/
#include"stdafx.h"
#include<iostream>
using namespace std;
int Divide(int a[],int first,int last)//选枢纽,划分
{
int i =first,j = last + 1;
while(true)
{
//从左向右扫描,碰到小于枢纽的,i自增,否则退出循环准备交换
while(a[++i] < a[first])
{
if(i == last) break;//如果扫描到了最右端,退出循环
}
//从右向左扫描,碰到小于枢纽的,j自减,否则退出循环准备交换
while(a[--j] > a[first])
{
if(j == first) break;//如果扫描到了最左端,退出循环
}
//如果相遇,退出循环
if (i >= j) break;
//交换左a[i],a[j]右两个元素,交换完后他们都位于正确的分区
swap(a[i],a[j]);
}
//经过相遇后,最后一次a[i]和a[j]的交换
//a[j]比a[first]小,a[i]比a[first]大,所以将基准元素与a[j]交换
swap(a[first],a[j]);
return j;
}
void QuickSort(int a[] ,int first,int last)
{
if(first >= last)//如果子序列为1,则直接返回
return;
int index = Divide(a,first,last);//划分序列,左小于a[index]小于右
QuickSort(a,first,index-1);//对左子序列排序
QuickSort(a,index+1,last);//对右子序列排序
}
int main()
{
int length = 0;
int i = 0;
cout << "请输入排序数组长度:" << endl;
cin >> length;
int a[100] = {0};
cout << "请输入排序数组:" << endl;
for(;i!=length;i++)
cin>>a[i];
cout << "快速排序:" << endl;
QuickSort(a,0,length-1);
for(int i = 0;i!= length;i++)
{
cout << a[i]<<" ";
}
cout << endl;
system("pause");
return 0;
}
#include<iostream>
using namespace std;
int Partition(int a[],int start,int end)
{
<span style="white-space:pre"> </span>if(a == NULL || start <0 || end <0)
<span style="white-space:pre"> </span>throw new std::exception("Invalid parameters");
int index =a[start];
while(start < end)
{
while(start<end && a[end]>index)
end--;
if(start < end)
a[start++] = a[end];
while(start<end && a[start]<index)
start++;
if(start < end)
a[end--] = a[start];
}
a[start] = index;
return start;
}
void Qsort(int arr[],int start,int end)
{
if(start == end)return;
if(start < end)
{
int index = Partition(arr,start,end);
Qsort(arr,start,index-1);
Qsort(arr,index+1,end);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[7] = {5,2,4,3,7,9,8};
Qsort(a,0,6);
int j = 0;
while(j!= 7)
{
cout << a[j] << " ";
j++;
}
cout <<endl;
system("pause");
return 0;
}
参考资料:http://www.cnblogs.com/yangecnu/p/Introduce-Quick-Sort.html