快速排序
快速排序是一种经常使用应用最广泛的一种排序算法,它可以算是冒泡排序的一种改进。
它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列;排序流程为先选取一个key(一般选取最左或最右)将数据分割两部分,再运用递归直到递归到只有一个元素。
单趟排序方法
左右指针法:
例如:
将其转化为代码为:
int part1(int* a, int left, int right) //每次确定一个位置
{
int begin = left;
int end = right;
int key = a[right];
while (begin<end)
{
while (begin<end && a[begin] <= key) //逐次找到
{
begin++;
}
while (begin<end && a[end] >= key) //逐次找到
{
end--;
}
swap(a[begin], a[end]);
}
swap(a[begin],a[right]);
return begin;
}
void QuickSort1(int* a, int left, int right)
{
if (left < right)
{
int div = part1(a, left, right);
QuickSort1(a, left, div - 1);
QuickSort1(a, div + 1, right);
}
}
挖坑法:挖坑法:首先找一个最左或者是最右端作为一个起始坑,保存坑中的值,然后如果在最左,那么就让left找一个比保存值大的,然后进行把这个值填坑,填完以后现在这个值的这个位置就变成了坑,然后我们继续让right在区间内找一个比保存值小的,找到以后填了刚才的坑,现在这个位置变成了新坑,这样一直继续下去,直left==right,这个时候坑无法再次变动,把保存的初始值填入坑中。这个就是挖坑法的单趟排序。
例如:
将其转化为代码为:
int port2(int*a, int left, int right)
{
int key = a[right];
while (left<right)
{
while (left<right && a[left] <= key) //
{
++left;
}
if (left<right)
{
a[right--] = a[left];
}
while (left<right && a[right] >= key)
{
--right;
}
if (left < right)
{
a[left++] = a[right];
}
}
a[left] = key;
return left;
}
void QuickSort(int* a, int left, int right)
{
if (left < right)
{
int div = port2(a, left, right);
QuickSort(a, left, div - 1);
QuickSort(a, div + 1,right);
}
}
前后指针法:
声明两个变量,一个prev,一个cur;开始将prev初始化成cur-1,判断prev+1是否等于cur,prev+1,不等于交换,逐次进行交换。
将其转化为代码为:
““
int part3(int* a, int left, int right)
{
int cur = left;
int prev = left - 1;
int key = a[right];
while (cur < right)
{
if (a[cur] < key && ++prev != cur) //如果++prev == cur,相遇说明没有数比key大,没有相遇则之前一个数大于key交换再判断
{
swap(a[cur], a[prev]);
}
++cur;
}
swap(a[++prev], a[right]);
return prev;
}
void QuickSort2(int*a, int left, int right)
{
if (left < right)
{
int div = part3(a, left, right);
QuickSort2(a, left, div - 1);
QuickSort2(a, div + 1,right);
}
}
““