您的位置:首页 > 其它

快速排序

2016-07-30 21:00 225 查看
1、快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

2、排序的过程







3、代码实现
三数取中法代码:

//优化一:三数取中法,避免出现最坏的情况
int GetMidIndex(int* a,int left,int right)
{
assert(a);
int mid = left + (right- left)/2;
if(a[left] > a[right])
{
if(a[mid] > a[left])
{
return left;
}
else
{
if(a[mid] > a[right])
return mid;
else
return right;
}
}
else//right大
{
if(a[mid] > a[right])
return right;
else//right 大
{
if(a[mid] > a[left])
return mid;
else
return left;
}
}
}
快速排序的代码:
int PartSort1(int* a,int left,int right)
{
int mid = GetMidIndex(a,left,right);
int key = a[mid];
int begin = left;
int end = right-1;

swap(a[mid],a[right]);
while(begin <end)
{
while(begin <end && a[end] >=key)
end--;
while(begin <end && a[begin] <key)
begin++;

if(begin < end)
swap(a[begin],a[end]);
}
if(a[begin] > a[right])
{
swap(a[begin],a[right]);
return begin;
}
else
return begin;

}
void QuickSort(int* a,int left,int right)
{
//快速排序的第二种优化,将插入排序与快速排序结合
assert(a);
if(left >= right)
return;
if(right -left < 16)
{
InsertSort(a+left,right-left+1);
return;
}
else
{
int ret = PartSort1(a,left,right);
QuickSort(a,left,ret-1);
QuickSort(a,ret+1,right);
}

}
另外两种快速排序的方法:
//挖坑法
int PartSort2(int* a,int left,int right)
{
int mid = GetMidIndex(a,left,right);
int key = a[mid];
int begin = left;
int end = right;//初始时的坑
swap(a[mid],a[right]);
while(begin < end)
{
while(begin < end && a[begin] <= key)
begin++;
if(begin < end)
{
a[end] = a[begin];//begin的位置变为坑
}
while(begin < end && a[end] >= key)
end--;
if(begin < end)
{
a[begin] = a[end];
}
}
//跳出循环后,begin的位置为坑,将key放入
a[begin] = key;
return begin;
}
//双指针法
int PartSort3(int* a,int left,int right)
{
int mid = GetMidIndex(a,left,right);
int key = a[mid];
swap(a[mid],a[right]);
int cur = 0;
int prev = -1;
while(cur < right)
{
if(a[cur] < key && (++prev != cur))
swap(a[cur],a[prev]);
cur++;
}
prev++;
swap(a[prev],a[cur]);
return prev;
}


4、时间复杂度
1)最好:O(N*logN)
在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(NlogN)。

2)最坏:O(N*N)(key取得的值接近最大或最小)
最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(N*N)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序 快速