2018-03-01快速排序

作者: 天驱丶 | 来源:发表于2018-03-01 02:11 被阅读14次

学习分而治之(divide and conquer, D&C)——快速排序

书中先讲了一个小案例,如果将一块长方形土地均匀分成方块,且分出的方块要尽可能大

两个要点:

  • 找出基线条件,这种条件必须尽可能简单
  • 不断将问题分解,直到符合基线条件(递归条件

案例分析
基线条件:一条边是另一条边的整数倍
递归条件:长边整除短边划出区域,剩余区域继续调用基线条件和递归条件

答案:1680 * 640的土地,按短边整数倍长分出2640640的区域,剩余区域为640400; 第二步分出240240区域,剩余区域为240160;第三步分出160160区域,剩余区域为160*80;因为160为80整数倍,所以可均匀分出的方块边长为80

ps: 该结论可搜索欧几里得算法

快速排序
  • 对于[]或者[1]这类数组,是不需要排序的,这是快速排序的基线条件

对于[33, 15, 10]这种数组应该怎么做呢?
首先,从数组种选择一个元素,这个元素被称为基准值(pivot)
然后根据剩余元素对比基准值,可分成小于基准值的数组和大于基准值的数组(递归条件)
最后,将两个数组再用此方法排序,直到满足基线条件,将两个数组和基准值相结合
得到[15, 10], 33, []
再将[15, 10]做排序得[10], 15, []
相结合得[10, 15, 33]

案例分析
基线条件:数组长度小于2
递归条件:选择其中一个元素作为基准值,与剩余元素比对,分割成小于和大于两个数组

答案(js版本):

function qsort(arr) {
  if (!(arr instanceof Array)) throw new Error('arr is not a Array');
  if (arr.length < 2) return arr;
  var pivot = arr[0];
  var less = [];
  var greater = [];
  for (i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) less.push(arr[i]);
    else greater.push(arr[i])
  }
  return qsort(less).concat([pivot]).concat(qsort(greater));
}

更新

快速排序最坏情况时间复杂度为O(n^2)
当基准值为第一个元素时,输入一个有序数组,其调用栈数为O(n),每次调用栈时间为O(n),其时间复杂度为O(n) * O(n) = O(n ^ 2)

改良

function qsort(arr) {
  if (!(arr instanceof Array)) throw new Error('arr is not a Array');
  if (arr.length < 2) return arr;
  var index = Math.floor(arr.length / 2);
  var pivot = arr[index]; // 基准值取中间元素
  var less = [];
  var greater = [];
  for (i = 0; i < arr.length; i++) {
    if (i === index) continue;
    if (arr[i] < pivot) less.push(arr[i]);
    else greater.push(arr[i])
  }
  return qsort(less).concat([pivot]).concat(qsort(greater));
}

更新 03-04

改良v2
对于有重复数据的数组,快排也对这部分数据进行了排序,其实这是没有必要的

function qsort(arr) {
  if (!(arr instanceof Array)) throw new Error('arr is not a Array');
  if (arr.length < 2) return arr;
  var index = Math.floor(arr.length / 2);
  var pivot = arr[index]; // 基准值取中间元素
  var less = [];
  var greater = [];
  var equal = [];
  for (i = 0; i < arr.length; i++) {
    if (i === index) continue;
    var item = arr[i];
    if (arr[i] < pivot) less.push(item);
    else if (arr[i] > pivot) greater.push(item);
    else equal.push(item)
  }
  return qsort(less).concat(equal).concat([pivot]).concat(qsort(greater));
}

相关文章

  • 2018-03-01快速排序

    学习分而治之(divide and conquer, D&C)——快速排序 书中先讲了一个小案例,如果将一块长方形...

  • 七大排序算法之快速排序

    七大排序算法之快速排序 @(算法笔记)[排序算法, 快速排序, C++实现] [TOC] 快速排序的介绍: 快速排...

  • 面试准备--排序

    堆排序 快速排序(simple) 快速排序(regular) 归并排序 Shell排序 插入排序 选择排序 冒泡排序

  • 排序

    插入排序 选择排序 冒泡排序 归并排序 快速排序* 三路快速排序

  • 算法笔记01-排序#2

    快速排序敢叫快速排序,那它一定得快。 快速排序 概述 快速排序也是分治排序的典型,它快,而且是原地排序。不过,要防...

  • PHP 实现快速排序

    导语 这篇了解下快速排序。 快速排序 快速排序(英语:Quicksort),又称划分交换排序(partition-...

  • 快速排序的Python实现

    目录 快速排序的介绍 快速排序的Python实现 快速排序的介绍 快速排序(quick sort)的采用了分治的策...

  • 数据结构与算法 快速排序

    起因:快速排序,又称分区交换排序,简称快排,之前没有了解过,抽空学习一下。 快速排序 1 快速排序 快速排序的定义...

  • 数组-快速排序

    采用快速方式对数组进行排序 快速排序百科:快速排序(Quicksort)是对冒泡排序算法的一种改进.快速排序是通过...

  • OC数据结构&算法

    更多整理资料尽在?一平米小站 目录 选择排序 冒泡排序 插入排序 快速排序 双路快速排序 三路快速排序 堆排序 选...

网友评论

    本文标题:2018-03-01快速排序

    本文链接:https://www.haomeiwen.com/subject/shmwxftx.html