zoukankan      html  css  js  c++  java
  • 排序学习之---快速排序

    一、前言

    快速排序是一种交换排序,它由C. A. R. Hoare在1962年提出。

    二、算法思想

    快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。

    然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

    动态效果示意图:

    排序(4):快速排序

    详细的图解往往比大堆的文字更有说明力,所以直接上图:

    排序(4):快速排序

    上图中,演示了快速排序的处理过程:

    初始状态为一组无序的数组:2、4、5、1、3。

    经过以上操作步骤后,完成了第一次的排序,得到新的数组:1、2、5、4、3。

    新的数组中,以2为分割点,左边都是比2小的数,右边都是比2大的数。

    因为2已经在数组中找到了合适的位置,所以不用再动。

    2左边的数组只有一个元素1,所以显然不用再排序,位置也被确定。(注:这种情况时,left指针和right指针显然是重合的。因此在代码中,我们可以通过设置判定条件left必须小于right,如果不满足,则不用排序了)。

    而对于2右边的数组5、4、3,设置left指向5,right指向3,开始继续重复图中的一、二、三、四步骤,对新的数组进行排序。

    python 代码

    # -*- coding:utf-8 -*-
     
    def QuickSort(input_list, left, right):
    	'''
    	函数说明:快速排序(升序)
    	Author:
    		www.cuijiahua.com
    	Parameters:
    		input_list - 待排序列表
    	Returns:
    		无
    	'''	
    	def division(input_list, left, right):
    		'''
    		函数说明:根据left和right进行一次扫描,重新找到基准数
    		Author:
    			www.cuijiahua.com
    		Parameters:
    			input_list - 待排序列表
    			left - 左指针位置
    			right - 右指针位置
    		Returns:
    			left - 新的基准数位置
    		'''	
    		base = input_list[left]
    		while left < right:
    			while left < right and input_list[right] >= base:
    				right -= 1
    			input_list[left] = input_list[right]
    			while left < right and input_list[left] <= base:
    				left += 1
    			input_list[right] = input_list[left]
    		input_list[left] = base
    		return left
     
    	if left < right:
    		base_index = division(input_list, left, right)
    		QuickSort(input_list, left, base_index - 1)
    		QuickSort(input_list, base_index + 1, right)
     
    if __name__ == '__main__':
    	input_list = [6, 4, 8, 9, 2, 3, 1]
    	print('排序前:', input_list)
    	QuickSort(input_list, 0, len(input_list) - 1)
    	print('排序后:', input_list)
    

      

    php代码

    1 递归实现

    找到当前数组中的任意一个元素(一般选择第一个元素),作为标准,新建两个空数组,遍历整个数组元素,

    如果遍历到的元素比当前的元素要小,那么就放到左边的数组,否则放到右面的数组,然后再对新数组进行同样的操作,

    不难发现,这里符合递归的原理,所以我们可以用递归来实现。

    使用递归,则需要找到递归点和递归出口:

    递归点:如果数组的元素大于1,就需要再进行分解,所以我们的递归点就是新构造的数组元素个数大于1

    递归出口:我们什么时候不需要再对新数组不进行排序了呢?就是当数组元素个数变成1的时候,所以这就是我们的出口。

    <?php
    /**
    * Created by PhpStorm.
    * User: brady
    * Date: 2018/10/10
    * Time: 11:33
    */


    /**
    * @author brady
    * @desc 快速插入排序
    * @param $arr 待排序的数组
    * @param string $sort asc升序 desc降序
    * @time 2018/10/10
    */
    function quick_sort($arr,$sort='asc')
    {
    echo json_encode($arr);
    echo "<hr>";
    //递归出口:数组长度为1,直接返回数组
    $length=count($arr);
    if($length<=1) return $arr;
    //数组元素有多个,则定义两个空数组
    $left=$right=array();
    //使用for循环进行遍历,把第一个元素当做比较的对象
    for($i=1;$i<$length;$i++)
    {
    //判断当前元素的大小
    if($sort == 'asc'){
    if($arr[$i]<$arr[0]){
    $left[]=$arr[$i];
    }else{
    $right[]=$arr[$i];
    }
    } else {
    if($arr[$i] > $arr[0]){
    $left[]=$arr[$i];
    }else{
    $right[]=$arr[$i];
    }
    }

    }
    //递归调用

    $left=quick_sort($left,$sort);
    $right=quick_sort($right,$sort);

    //将所有的结果合并
    return array_merge($left,array($arr[0]),$right);
    }

    $arr=array(6,3,8,6,4,2,9,5,1);
    //调用
    echo "<pre>";
    print_r($arr);
    print_r(quick_sort($arr,'desc'));

      

  • 相关阅读:
    Python-模块
    POJ 1631 nlogn求LIS
    POJ 1274 二分图匹配
    POJ 3661 DP
    POJ 3662 二分+Dijkstra
    POJ 3666 DP
    POJ 2373 单调队列优化DP
    祝自己生日快乐
    POJ 2385 DP
    POJ 3122 Pie 二分答案
  • 原文地址:https://www.cnblogs.com/brady-wang/p/9765321.html
Copyright © 2011-2022 走看看