什么是快排
定义:
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中
的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右
子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。
快排分类
- hoare版本
这里是hoare版本:
先找一个Key来做比较的筹码,将begin和end都对应其位置。
如果Key取右就从begin开始走(不然会错过向交的位置循环就会进入死循环)Begin从左往右取大 End从右往左取小当同时去到后 再把值进行交换。
经过循环判断就将2和9进行交换最终两指针相遇再将Key值和相交值一换这样就完成了一次循环,这样做保证了比Key小的再key的左边比key大的再右边。然后再进行分治处理递归。
int PartSort1(int* a, int left, int right);
{
int mid = Midsearch(a, left, right)
int end = right;
swap(a[end], a[mid]);
int key = a[end];
int begin = left;
while (begin < end)
{
while (a[end]<key&&end>begin)
{
end--;
}
while (a[begin]>key&&begin > end)
{
begin++;
}
swap(a[end], a[begin]);
}
swap(a[right], a[begin]);
return begin;
}
- 挖坑法
挖坑的方法也是大同小异
这里就不用考虑那边先走了,给定一个Key=end如果从begin开始走 当begin大于key就和end进行交换这样就把大的交换到后边然后左边找小找到小的再把之前begin已经传过去的位置进行赋值剩下的就大同小异了。
int PartSort2(int* a, int left, int right);
{
int begin = left;
int end = right;
int key = end;
while (begin < end)
{
while (a[begin]>key&&begin < end)
{
begin++
}
a[end] = a[begin];
while (a[end] < key&&begin < end)
{
end--;
}
a[begin] = a[end];
}
a[begin] = key;
return begin;
}
- 前后指针版本
定义两个指针prev指向cur的前一个,此时取key为end值,只要cur的值小于key就将prev和cur交换并将prev++,如果遇到比key大就++cur不动prev直到遇到小的再交换这样就把大的挪到后边。
int PartSort3(int* a, int left, int right);
{
int key = a[right];
int cur = begin;
int prev = begin - 1;
while (cur < right)
{
if (a[cur] < key)
{
if(prev==NULL)
{
continue;
}
swap(a[prev], a[cur]);
prev++;
}
else
cur++;
}
prev++;
swap(a[cur], a[prev]);
return prev;
}
分治代码:
void QuickSort(int* a, int left, int right);
{
if (left >= right)
{
return;
}
int div = PartSort1(a, left, right);//Partsort2//Pareort3;
QuickSort(a, left, div - 1);
QuickSort(a, div+1, right);
三数取中
因为当快排处理越有序的学列其效率就越低,前人研究了三数取中,这样Key就不会是最大值,保证了快排的效率。
int Midsearch(int * a, int left, int right)
{
int begin = left;
int end = right;
if (a[begin] < a[mid])
{
if (a[mid] < a[end])
{
return mid;
}
else if (a[begin] > a[end])
{
return begin;
}
else
{
return end;
}
}
else // begin >= mid
{
if (a[mid] > a[end])
{
return mid;
}
else if (a[begin] < a[end])
{
return begin;
}
else
{
return end;
}
}
}