快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
1.左右指针法
在数组的左和右分别定义一个指针,begin指针从前往后遍历找到一个比key大的数据停止,end从后往前遍历找到一个比key小的数据,此时当begin小于end时交换begin和end的值,小的数就交换到前面了,大的数就交换到后面了,当while循环结束时begin<=end交换begin和key的值,此时begin左边的值都比他小,右边的值都比他大,递归返回begin的值,以此类推先让begin的左边值有序,然后递归返回begin右边的值,排序,begin右边的值有序排序完成。
代码
int PartSort1(int *a, size_t left, size_t right)//左右指针
{
int key = a[right];
int begin = left;
int end = right;
while (begin < end)
{
while (begin < end&&a[begin] <= key)
{
++begin;
}
while (begin < end&&a[end] >= key)
{
end--;
}
if (begin < end)
{
swap(&a[begin], &a[end]);
}
}
swap(&a[begin], &a[right]);
return begin;
}
2.前后指针法
定义一个cur和prev,prev=cur-1,此时令cur等于数组的第一个元素,而prev是cur的上一个元素。当a[cur]小于key且不等于prev时交换prev和cur的值,cur++,prev总是指向比key大的元素的上一个元素
代码
int PartSort3(int *a, int left, int right)//前后指针
{
int cur = left;
int prev = cur - 1;
int key = a[right];
while (cur < right)
{
if (a[cur] < key&& cur!=prev)
{
prev++;
swap(&a[cur], &a[prev]);
}
cur++;
}
prev++;
swap(&a[prev], &a[cur]);
return prev;
}
3.挖坑法
基本思路:定义两个指针begin一个指向起始位置,end一个指向最后一个元素的位置。begin寻找比基数(temp)大的数字,找到 后将begin的数据赋给end,begin成为一个坑,然后end寻找比基数(temp)小的数字,找到将end的数据赋给begin,end成为一个新坑,循环这个过程,直到begin指针与end指针相遇,然后将temp的数据返回给那个坑,然后进行递归操作。
int PartSort2(int *a, size_t left, size_t right)//挖坑
{
int begin = left;
int end = right;
int tmp = a[left];
while (begin < end)
{
while (begin<end&&a[end]>=tmp)
{
end--;
}
if (begin < end)
{
a[begin] = a[end];
}
while (begin < end&&a[begin] <= tmp)
{
begin++;
}
if (begin < end)
{
a[end] = a[begin];
}
}
a[begin] = tmp;
return begin;
}
完整代码
#include<stdio.h>
#include<Windows.h>
#include<assert.h>
void swap(int *i, int *j)
{
int tmp =*i;
*i = *j;
*j = tmp;
}
int PartSort1(int *a, size_t left, size_t right)//左右指针
{
int key = a[right];
int begin = left;
int end = right;
while (begin < end)
{
while (begin < end&&a[begin] <= key)
{
++begin;
}
while (begin < end&&a[end] >= key)
{
end--;
}
if (begin < end)
{
swap(&a[begin], &a[end]);
}
}
swap(&a[begin], &a[right]);
return begin;
}
int PartSort2(int *a, size_t left, size_t right)//挖坑
{
int begin = left;
int end = right;
int tmp = a[left];
while (begin < end)
{
while (begin<end&&a[end]>=tmp)
{
end--;
}
if (begin < end)
{
a[begin] = a[end];
}
while (begin < end&&a[begin] <= tmp)
{
begin++;
}
if (begin < end)
{
a[end] = a[begin];
}
}
a[begin] = tmp;
return begin;
}
int PartSort3(int *a, int left, int right)//前后指针
{
int cur = left;
int prev = cur - 1;
int key = a[right];
while (cur < right)
{
if (a[cur] < key&& cur!=prev)
{
prev++;
swap(&a[cur], &a[prev]);
}
cur++;
}
prev++;
swap(&a[prev], &a[cur]);
return prev;
}
void QuickSort(int*a, int left,int right)
{
assert(a);
if (left >= right)
{
return;
}
int div = PartSort1(a, left, right);
QuickSort(a,left, div - 1);
QuickSort(a,div + 1,right);
}
void PintSort(int *a, size_t n)
{
for (int i = 0; i < n; ++i)
{
printf("%d ", a[i]);
}
}
int main()
{
int a[] = { 32,12,15,18,23,51,17};
int n = sizeof(a) / sizeof(a[0]);
QuickSort(a, 0, n-1);
PintSort(a,n);
system("pause");
return 0;
}