图解算法笔记|快速排序

211 阅读1分钟

图解算法笔记|快速排序

1. 分而治之

分而治之是利用递归的原理将大的样本转换成 小的样本,再去就解决他

例题1: 1680x640的农场要化分成尽可能大的正方形小块?

如果要用递归来解决,需要确定两个地方,一个基线条件,另一个是递归条件

划分最大块的问题是一个求最大 公约数的问题,而最大公约数求法是辗转相除法,也就是最大公约数是同时满足上面长和宽的除以它为正数的情况,至于如何求最大公约数:

1680 / 640 = 2 (余 400)
640 / 400 = 1(余240)
400 / 240 = 1(余160)
240 / 160 = 1 (余80)
160 / 80 = 2 (余0)

我们发现上面其实就是一个递归,现在我们来构建递归函数,构建递归函数有两个条件必须要搞清楚,一个是基线条件还有递归体

基线条件从上面可以看出,就是长/宽的模为0,也就是 x%y==0结束,

我们通过代码实现一下这个例子:

php:

<?php

function findMaxLen($len,$width){
    $m = $len%$width;
    if ($m==0){
        return $width;
    }
    return findMaxLen($width,$m);
} 

$res = findMaxLen(1680,640);
var_dump($res);

golang:

package main

import "fmt"

func findMaxLen(len, width int) int {
	var m int = len % width
	if m == 0 {
		return width
	}
	return findMaxLen(width, m)
}

func main() {
	num := findMaxLen(1680, 640)
	fmt.Println(num)
}

python:


def findMaxLen(len,width):
    m=len%width
    if m==0:
        return width
    return findMaxLen(width,m)

print(findMaxLen(1680, 640))

2.快速排序

快速排序是利用递归实现的一种排序方式,随机选取一个元素作为参照,利用它可以将样本分成两部分,比他大的,比他小的, 但是两侧的样本可能也是无序,所以在两侧递归的调用上述方法,再选择一个参照,如此往复,直到剩下一个,这样随后一个可以跟参照物做比较了,而且是有序的

下面是实现方法:

python:

def quicksort(array):
    if len(array)<2:
        return array 
    pivot=array[0]
    less=[i for i in array[1:] if i<=pivot]
    greater=[i for i in array[1:] if i>pivot]
    return quicksort(less)+[pivot]+quicksort(greater)
print(quicksort([1,2,30,40,5]))

php:

<?php

function quickSort($arr){
    if (count($arr)<=1){
        return $arr;
    }
    $pivot = array_shift($arr);
    $less = [];
    $greater = [];

    foreach($arr as $v){
        if($pivot>$v){
            array_push($less,$v);
        }else{
            array_push($greater,$v);
        }
    }

    $less = quickSort($less);
    $greater = quickSort($greater);
    return array_merge($less, array($pivot), $greater);
}
$a = array(1,30,2);
$res = quickSort($a);
var_dump($res);

golang:

package main

import "fmt"

func main() {
	num := []int{1, 20, 3}
	fmt.Println(qsort(num))
}

func qsort(num []int) []int {
	if len(num) <= 1 {
		return num
	}
	pivot := num[0]
	var less []int
	var greater []int
	for _, value := range num[1:] {
		if value <= pivot {
			less = append(less, value)
		} else {
			greater = append(greater, value)
		}
	}
	less = qsort(less)
	greater = qsort(greater)
	res := append(less, pivot)
	res = append(res, greater...)
	return res
}