码迷,mamicode.com
首页 > 编程语言 > 详细

快速排序

时间:2015-05-09 15:05:48      阅读:361      评论:0      收藏:0      [点我收藏+]

标签:快速排序   基本排序算法   

快速排序

思想:

快速排序的思想巧秒,利用分治的思想,可以极快排序数组。其基本思想分两步:
1. 给你一个数组,让你选择数组中的任意一个数作为基数,然后让数组中所有比基数小的数都放在放在基数的左边,所有比基数大的数放在基数的右边。
2. 将刚才基数的位置作为中点,将数组中基数左边的所有元素做1操作,将基数右边的所有元素做1操作。
看到步骤2,就很容易想到这里面是递归调用的。所以我们的关键任务就是如何让第一步高效快速实现。

代码:

先看代码,我们来实现步骤1:


// 选n为基准, 使左边的数都比它下, 右边的数都比它大
// 返回基准在数组中的位置
int insertToMid(int arr[], int left, int right, int n)
{
    int i = left;
    int j = right;
    while (i < j)
    {
        for (; i < j; --j)
        {
            if (arr[j] < n)
            {
                arr[i] = arr[j];
                ++i;
                break;
            }
        }

        for (; i<j; ++i)
        {
            if (arr[i] > n)
            {
                arr[j] = arr[i];
                --j;
                break;
            }
        }
    }
    arr[i] = n;
    return i;
}

解释一下:选取的基数是n,是外部传入的(后面可以看到其实是数组中的第一个元素)。然后让i和j分别指向数组的开头和结尾。从数组的最后开始向前找第一个比n小的数,将这个数与赋值到i位置上(比n小的数放到n的左边)。然后又从i+1位置往后找第一个比n大的数,将这个数赋值到j位置上(比n大的数放到n的右边)。(由于第一路找第一个比n小的数的时候,是总末尾开始找的,所以可以保证现在赋值的位置的右边都是比n大的数。),直到i=j的时候,就是n该放到的中间位置。然后返回i的索引位置。

看看图解:
技术分享

到这里我们完成了步骤1(选取基数,排序后使基数左边的数都小于基数,让基数右边的数都大于基数,当然这里的排序不是严格的从低到高,而是一个范围大小的归类。这样基数右边的所有数都大于基数左边的数了

然后再完成步骤2就简单了,看看代码:

//快速排序
void quickSort(int arr[], int left, int right)
{
    if (left < right)
    {
        int mid = insertToMid(arr, left, right, arr[left]);
        quickSort(arr, left, mid - 1);
        quickSort(arr, mid + 1, right);
    }
}

解释:这里之所以让insertToMid()返回中间值就是为了进行递归调用,将基数左边的所有数执行步骤1,右边的所有数也执行步骤1。到最后只剩两个数的时候就,就一定为有序数列了。

图解:
技术分享

总结:

快速排序的时间辅助读为 O(nlog2(n)),其快慢主要区别就是在步骤1上,当然是先步骤1可以采取自己的方法,只要能达到要求就行了。这种分治的思想还是非常先进的,感觉自己明白的又多了。

快速排序

标签:快速排序   基本排序算法   

原文地址:http://blog.csdn.net/u013647382/article/details/45600647

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!