基本思想
- 通过一趟排序将待排序列分割成独立的两个子序列,其中一部分序列的数字均比另一部分的数字小,则可分别对这两个子序列继续进行排序,以达到整个序列有序。
//在各种内部排序中,快速排序被认为是目前最好的一种排序方法。
实现逻辑
- 从数列中挑出一个元素,称为 “基准”(pivot),
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
- 在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
//c实现代码
void quicksort(int k[],int s,int t)
{
int i,j,temp;
if(s<t)
{
i=s;
j=t+1;
while(1)
{
do i++;
while(k[i]<k[s]&&i<t); //重复i++的操作
do j--;
while(k[j]>k[s]&&j>s); //重复j++的操作
if(i<j)
{
temp=k[i]; //交换k[i]和看k[j]的位置
k[i]=k[j];
k[j]=temp;
}
else
break;
}
temp=k[s]; //交换基准元素与k[j]d的位置
k[s]=k[j];
k[j]=temp;
quicksort(k,s,j-1); //递归排序基准元素前面的子序列
quicksort(k,j+1,t); //递归排序基准元素后面的子序列
}
}
//完整c代码
#include<stdio.h>
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void quicksort(int k[],int s,int t)
{
int i,j,temp;
if(s<t)
{
i=s;
j=t+1;
while(1)
{
do i++;
while(k[i]<k[s]&&i<t); //重复i++的操作
do j--;
while(k[j]>k[s]&&j>s); //重复j++的操作
if(i<j)
{
swap(&k[i],&k[j]); //交换k[i]和看k[j]的位置
}
else
break;
}
swap(&k[s],&k[j]); //交换基准元素与k[j]d的位置
quicksort(k,s,j-1); //递归排序基准元素前面的子序列
quicksort(k,j+1,t); //递归排序基准元素后面的子序列
}
}
int main()
{
int i,n;
int a[101];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
quicksort(a,0,n-1);
for(i=0;i<n-1;i++)
printf("%d ",a[i]);
printf("%d\n",a[n-1]);
return 0;
}
优化改进
- 场景分析:
递归是一种使用相同的方法,通过解决问题的子集以达到解决整个问题的方法,是一种使用有限代码解决“无限”计算的方法。在C/C++语言中递归表现在函数对自身的直接/间接的调用上,在实现上,递归依赖于语言的运行时调用堆栈,使用堆栈来保存每一次递归调用返回时所需要的条件。递归通常具有简洁的编码和清晰的思路,但这种简洁是有代价的。一方面,是函数调用的负担;另一方面,是堆栈占用的负担(堆栈的大小是有限的)。 - 改进思路:
递归转化为迭代。迭代的思想主要在于,在同一栈帧中不断使用现有数据计算出新的数据,然后使用新的数据来替换原有数据。
//c代码
//c++代码