排序(四) 之快速排序


 

一、快速排序

  快速排序应该时排序算法中最好的一种,看看它的命名都显得那么诚实。快速排序也是我们必须掌握的一种排序算法,因为面试的时候绝大概率是要出现的。

 

二、排序原理

这里假如数据array[10]进行排序

  1. 首先找个基准元素tmp,一般为第一个数据(tmp = array[0], left = 0, rgint = 9)
  2. 从最右边(right = 9)开始取出数据(array[9])与基准数据比较,比基准数据大,则不变(这里默认排序完成时从小到大的),right–(这时right=8),继续拿array[8]与基准数据比,直到array[right] 比基准数数小,这时把array[right] 的值赋给array[left]
  3. 从最左边(left = 0)开始取出数据(array[0])与基准数据比较,比基准数据小,则不变(这里默认排序完成时从小到大的),left++(这时left=1),继续拿array[1]与基准数据比,直到array[left] 比基准数数大,这时把array[left] 的值赋给array[right]
  4. 循环 2、3步骤,直到left >= right
  5. 这时我们把数据分为两个[0, left - 1] ,[right, 9],递归进行上面的1,2,3,4步骤。
  6. 直到数组不能再分。

网上找个图(还是看图):
在这里插入图片描述

 

三、代码示例

int quick_sort(int *array, int start, int end)
{   
    int right, left;
    int tmp;
     
    if (NULL == array)
        return -1;
     
    left = start;
    right = end;
     
    /*递归退出判断*/
    if (left < right) {
        tmp = array[left];
         
        while (left < right) {
            while (left < right && array[right] > tmp)
                right --; 
            array[left] = array[right];
             
            while (left < right && array[left] < tmp)
                left ++; 
            array[right] = array[left];
        }
         
        array[right] = tmp;
        quick_sort(array, start, left - 1);
        quick_sort(array, right + 1, end);
    }
     
    return 0;
}

 

四、算法分析

  1. 当分区选取的基准元素为待排序元素中的最大或最小值时,为最坏的情况,时间复杂度和直接插入排序的一样,移动次数达到最大值max = 1+2+…+(n-1) = n*(n-1)/2 = O(n2) 此时最好时间复杂为O(n2)
  2. 当分区选取的基准元素为待排序元素中的"中值",为最好的情况,时间复杂度为O(nlog2n)。
  3. 快速排序的空间复杂度为O(log2n).
  4. 当待排序元素类似[6,1,3,7,3]且基准元素为6时,经过分区,形成[1,3,3,6,7],两个3的相对位置发生了改变,所是快速排序是一种不稳定排序。

 

五、测试

sort.c

int main(int argc, char **argv)
{
	int i, length;
    // int buf[5] = {
    //      16, 32, 8, 12, 13 
    // };
	int buf[] = {112, 5,1,11, 34, 10, 111,1234,44,33,23,56,77,88,43,41,2,4,19,13,3,8,6,0,9};
	//int buf[10]={4,1,3,2,16,9,10,14,8,7};
	
	length = sizeof(buf)/sizeof(int);
	// heap_sort(buf-1, length);
    // shell_sort(buf, length, 2);
    quick_sort(buf, 0, length - 1);

	for(i = 0; i < length; i++)
		printf("%d\t ", buf[i]);	
	printf("\n");	

	return 0;
}

结果输出:
在这里插入图片描述

 
 
 
 
 
 
 
关注公众号"小败日记",搬砖过程遇到的问题,大家一起探讨,资源共享

小败日记公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值