快速排序
快速排序是对冒泡排序的一种改进,它的基本思想是,通过一趟排序将待排记录分割成独立的两个部分其中一部分记录的关键字均比另一部分记录的关键字校=小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。
时间复杂度:
平均O(nlogn)
最差的情况就是每一次取到的元素就是数组中最小/最大的,快速排序,越有序,越慢,完全有序1,2,3,4,5,6,7,8,9这种情况并不是退化成冒泡排序,而是选择排序,时间复杂度O(n^2)。
综上所述:快速排序最差的情况下时间复杂度为:O( n^2 )
空间复杂度:
最优的情况下空间复杂度为:O(logn) ;每一次都平分数组的情况
最差的情况下空间复杂度为:O( n )
不稳定
来回跳跃式交换数据
逻辑步骤:
假设数组中有n个待排序数字,
1.设置一个low 和一个high
low指向当前待排序数组的最左边的下标
high指向当前待排序数组的最右边的下标
2.设置基准:将0号下标的数字放入temp中间变量中,
3.然后high指针从后往前走依次与基准temp比较,若小于基准temp,则将该数字放入0号下标,
此时,刚才放入0号位的数字位置空缺,然后low指针从前往后然后走,依次与基准temp比较,若有大于基准temp的,放入后面的空格子,
4.重复第3步
5.若low和high相遇,则空缺位置为基准temp的最终位置,将基准放入此处,基准左边的数比基准小,基准右边的数比基准大
6.若左边只有一个数字,则左边已经有序,左边不需要再排序
7.若超过两个数字,将左边的数字根据上面的方法继续划分
//递归写法:
#include <stdio.h>
#include <assert.h>
//1.一次排序的程序
int Partition(int *arr, int low, int high)//下标可取
{
assert(arr != NULL);
int temp = arr[low];//设置基准
while(low < high)
{
while((low<high) && (arr[high] >= temp))//若后面的数字大于基准,则不发生移动high向左移动
{
high--;//不加判断条件low<high可能发生high<low
}
if(low == high)//low=high,说明已经完成一趟的比较,跳出循环
{
break;
}
else//否则,说明arr[high]的值小于基准temp,则将arr[high]的值放入arr[low]中
{
arr[low] = arr[high];
}
}
arr[low] = temp;//完成一次排序,low和high处于同一位置,将基准的值放入此处,此时左边的值小于此处值,右边的值都大于此处
return low;//返回这个位置,来判断左边是否需要再排序,>1时则需要继续排序
}
static void Quick(int *arr, int start,int end)//马甲函数
{
int par = Partition(arr,start,end);//先划分一次
if(par > start+1)//返回基准的位置,若大于1,继续划分
{
Quick(arr,start,par-1);
if(par < end-1)
{
Quick(arr,par+1,end);
}
//QuickSort(arr,len);
}
}
void QuickSort(int *arr, int len)
{
Quick(arr,0,len-1);
//int par = Partition(arr,0,len-1);
//if(par > 0+1)
//{
// QuickSort(arr,len);
//}//无法递归,没有起始参数,传len变成死递归
}
int main()
{
int arr[] = {10,11,4,6,82,2,5,9,22,1};
QuickSort(arr,sizeof(arr)/sizeof(arr[0]));
return 0;
}