分治之快速排序
复习了一下快速排序,又忘了,这次加深一下印象。
首先看一下快排的实现过程
利用分治的思想,把一个数字一分为二,接着对子数组进行同样的操作,直到数组小到我们可以轻易进行排序为止。贴一下伪代码
Quick_sort(A,left,right)
if left<right then
p=Partition(A,left,right)
Quick_sort(A,left,p-1)
Quick_sort(A,p+1,right)
end if
可以看出这一步非常简单,就是一个不断分割,不断递归的过程,其中最关键的一步就是Partition这个函数,这个函数是一个非常关键的操作,我们看一下这个操作的伪代码
Partition(A,left,right)
if left<right then
i=left,j=right,x=A[low]//i和j相当于两个指针,一个从左往右进行查找,另一个从右往左进行
while(i<j&&A[j]>=x)//与x进行比较,直到j小于x
j--
end while
if(i<j)
A[i]=A[j]//把比x小的数j赋值给i指向的位置,不要怕i处的位置丢失,因为i现在的值已经赋给了x
i++
end if
while(i<j&&A[i]<=x)//同理
i++
end while
if(i<j)
A[j]=A[i]
j--
end if
end if
x=A[i]
return i
虽然我在代码注释里已经说得很清楚了,但是为了加深印象,我贴几张图演示一下Partition的排序过程。
Partition最后一步的时候千万别忘了把x再赋给i
最后,是完整的C++源代码:
/*date: 2020年1月6日
Author: Chauncy*/
#include<iostream>
using namespace std;
int Partitions(int a[], int low, int high)
{
if (low >=high) //先检查左右条件
return -1;
int i = low, j = high, x = a[low];
while (i < j)
{
while (i < j && a[j] >= x)//从右向左找到第一个小于x的
j--;
if (i < j)
a[i++] = a[j];//填坑之后i++,如果是考试填空或简答题,一般不是先用a[j]填坑,是先找到i,j的位置,然后才交换a[i],a[j]的值。
while (i < j && a[i] <= x)//从左向右找第一个大于x的数
i++;
if (i < j)
a[j--] = a[i];
}
a[i] = x; //把最开始取出来的x放到i处
return i;
}
void QuickSort(int a[], int low, int high)
{
if (low < high)
{
int q = Partitions(a, low, high);
QuickSort(a, low, q - 1);
QuickSort(a, q + 1, high);
}
}
int main()
{
int n;
cin>>n;
int B[n];
for(int i=0;i<n;i++)
{
cin>>B[i];
}
QuickSort(B,0,n-1);
for(int i=0;i<n;i++)
{
cout<<B[i]<<endl;
}
return 0;
}