c语言快速排序_D&C思想-快速排序算法

b8d5428ea2f6dd0a57a65d78a760d3f9.png

只能解决一种问题的算法,用处必然是有限的.所以今天介绍一种解决问题的思路,一个可以让我们使用的工具.Divide and Conquer 分而治之

先来说明一下D&C的工作原理:

(1) 找出简单的基线条件
(2) 确定如何缩小问题的规模,使其符合基线条件.

首先看一个例子

10  20  30

比如我们要把上面几个数字相加,你首先想到的是什么? 我开始的时候,想到的是循环,我想你们应该也有和我想得一样的吧.

那好,今天我们换个思路,用我们的D&C的思想来解决.

  • 上面的基线条件是什么?
  • 如何缩小它的规模,来符合我们的基线条件?

我们在计算一个整形数组的和的时候,最简单的情况是什么?

1.数组为空 2.数组只有一个元素

大多数情况下,我们要计算数组的和,那这个数组一般情况下是不会为空的.所以,我们的最理想的情况就是数组只有一个元素.基线条件已确定.

接下来,该如何将它分解到基线情况呢?

1.把第一个元素拆出来: 10 + sum(20+30)
 2.把第二个元素拆出来: 10 + sum(20 + sum(30))

一层一层递进,就可以求出数组所有元素的和. 好,下面看一下python代码:

def sum(L):

    #递归的退出条件
    if l == []:
        return 0
    return l[0] + sum(l[1:])

D&C思想了解了后,最后我们再看一下快速排序

快速排序是一种常用的排序算法,比选择排序快的多.

对一个数组进行排序,那什么情况是基线呢?其实和数组求和一样.如果这个数组是空,或者数组的只有一个元素,那么排序就很简单了,就是它自己.

先对一个含有三个元素的数组排序

7  2  10

应用快速排序时,得先选择一个元素作为基准值(pivot),一般情况下,我们选择第一个元素作为基准值.

对于上面的数组,选择7作为基准值.

然后,向后遍历,遇到一个小于基准值的元素,放到基准值的左边.遇到一个大于基准值的元素,放到基准值的右边.这被称为分区(partitioning).

看一下现在的情况:

  • 一个由所有小于基准值的数字组成的字数组;
  • 基准值;
  • 一个由所有大于基准值的数组组成的字数组.

现在,对于这个只有三个元素的数组,已经排序完毕.

然后,看一下含有4个元素的数组

12  8  2  15

首先,12作为基准值,进行排序,第一轮完毕之后,是这个样子的:

8  2  12  15

现在,排列情况是:

| <基准值 | 基准值 |  >基准值 |

大于基准值的部分,只有一个元素,不需要排序了. 小于基准值的部分,两个元素,同样,我们按照上面的方法,递归调用,进行排序.最后,得到了:

2  8  12  15

那,对于5个元素,6个元素,上千,上万的元素呢?同样啊,进行递归的调用,就可以排序了.

快速排序的python代码:

def quick_sort(arr):
    if len(arr) < 2:
        return arr
    else:
        pivot = arr[0]
        less = [i for i in arr[1:] if i < pivot]
        greater = [j for j in arr[1:] if j > pivot]
        return quick_sort(less) + [pivot] + quick_sort(greater)

print(quick_sort([2,8,12,15,32,4,56,12]))

输出结果:

[2, 4, 8, 12, 15, 32, 56]

快速排序的时间复杂度为O(nlogn)

注意:递归的退出条件一定要给出

最后,看一下快速排序的c语言实现

#include<stdio.h>

#define N 5

int arr[N] = {23,65,156,545,32};

void quick_sort(int arr[],int low,int high)
{
    //base value
    int pivot = arr[low];
    int i = low;
    int j = high;
    if(i > j)
       return;

    while(i < j)
    {
        while((i < j) && (arr[j] >= pivot))
            j--;
        if(i < j)
            arr[i] = arr[j];
        while((i < j) && (arr[i] <= pivot))
            i++;
        if(i < j)
            arr[j] = arr[i];
    }

    arr[i] = pivot;
    quick_sort(arr,low,i-1);
    quick_sort(arr,j+1,high);

}

void main()
{
    int i;
    quick_sort(arr,0,4);
    for(i = 0;i < 5;i++)
    {
        printf("%d n",arr[i]);
    }
}

c语言的代码相对于python代码有点复杂.c代码中定义了两个指针,来指向正在遍历的元素,一个指向小于pivot的,一个指向大于pivot的.

661fe3a59616feb42e7cf37b549b9b1a.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值