源代码:
https://github.com/lzneu/Algrithm_python

O(n*logn)级别的排序:
|-归并排序
    分成log(n)个层级 每个层级进行O(n)排序
    每次归并时 开辟一个新的存储空间作为辅助 因此需要使用O(n)多的空间
    用三个索引进行归并 时间复杂度O(n)
    当n比较小的时候 由于复杂度前面都有常数项 因此 归并有时比插入排序满 可在此处进行优化
    自底向上的归并排序 由于没有用到数组下标 因此可以用于链表排序O(n*logn)
|-快速排序
    选定元素挪到正确位置,挪动的过程也是分离大于选定元素 和 小于选定元素的过程
    递归选定元素两侧的数组进行快排
    当集合完全有序时 快拍退化成了O(n^2)级别 这是可以通过随机选取每次快排的枢轴来优化
|-二路快排
    当集合中的元素大量重复时 相等于temp的元素很多 导致数据集合分成了两个不平衡的部分 ,改进patition函数的切分方式,变成双路快排

|-三路快排
    分割时将集合分成三部分
        =temp
        <temp
        >temp
        递归的分割后两个部分

总结: 归并排序 和 快速排序 都使用了分治算法
扩展应用:
    实现方法见我的github: https://github.com/lzneu/Algrithm_python
    |- 求逆序对
        完全有序的数列 逆序对数量为0 逆序的数列 逆序对数量最多
        可以通过求逆序对的数量来表示数列的有序程度
        暴力解法O(n^2)
        归并排序求逆序对 O(n*logn) swap一次 说明有一个逆序对 可以叠加

|- 求数组的第N大元素
        利用快速排序 patition只留下 符合要求的那部分 知道 temp就是第n个
        复杂度O(n)

import datetime
import random
import numpy as np
# 生成一个近乎有序的数组
def genNearlyOrderArray(n, swapTimes):arr = list(range(n))for i in range(swapTimes):x = random.randint(0, n)y = random.randint(0, n)swap(arr, x, y)return arrdef genRandomArray(n, start=0, end=10000):return np.random.randint(start, end, size=n)def aTestSort(sortName, arr, n):t_start = datetime.datetime.now()sortName(arr, n)t_end = datetime.datetime.now()  # 记录函数结束时间)long = (t_end - t_start).total_seconds()if isSorted(arr, n):print("sortName: %s, time: %f s" % (sortName.__name__, long))else:print('Sort ERROR!')def swap(arr, i, j):temp = arr[i]arr[i] = arr[j]arr[j] = tempdef isSorted(arr, n):for i in range(n - 1):if (arr[i] > arr[i + 1]):return Falsereturn True# 将arr[l...mid] 和 arr[mid+1...r]两部分合并
def __merge(arr, l, mid, r):aux = arr[l: r + 1]i = lj = mid + 1for k in range(l, r + 1):if (i > mid):arr[k] = aux[j - l]j += 1elif (j > r):arr[k] = aux[i - l]i += 1elif (aux[i - l] < aux[j - l]):arr[k] = aux[i - l]i += 1else:arr[k] = aux[j - l]j += 1def insertionSort4Ms(arr, l, r):# if l >= r:#     returnfor i in range(l + 1, r + 1):j = itemp = arr[i]while ((j > l) and (arr[j - 1] > temp)):arr[j] = arr[j - 1]j -= 1arr[j] = tempreturn# 递归的使用归并排序arr[l...r]
def __mergeSort(arr, l, r):# if l >= r:#     return# 此处优化 在n比较小时 调用插入排序if (r - l) <= 15:insertionSort4Ms(arr, l, r)returnmid = int((l + r) / 2)__mergeSort(arr, l, mid)__mergeSort(arr, mid + 1, r)# 若有序 无需再合并了if (arr[mid] > arr[mid + 1]):__merge(arr, l, mid, r)def mergeSort(arr, n):# 表示私有__mergeSort(arr, 0, n - 1)# 自底向上归并排序(由于没有用到数组下标 因此可以用于链表排序)
def mergeSortBU(arr, n):size = 1while (size <= n):i = 0while (i + size < n):__merge(arr, i, i + size - 1, min(i + size + size - 1, n - 1))i += (size + size)size += size# 对arr[l...r]进行partition
def __partition(arr, l, r):# 此处对快排进行优化,随机中选取元素作为枢轴swap(arr, l, random.randint(l, r))temp = arr[l]j = lfor i in range(l + 1, r + 1):if (temp > arr[i]):swap(arr, j + 1, i)j += 1swap(arr, j, l)return j# 对arr[l...r]进行快速排序
def __quickSort(arr, l, r):# if (l>=r):#     return  # 别忘了这个啊 要不然死循环了if (r - l) <= 15:# 元素个数少的时候用插入排序insertionSort4Ms(arr, l, r)returnp = __partition(arr, l, r)__quickSort(arr, l, p - 1)__quickSort(arr, p + 1, r)# 快速排序
def quickSort(arr, n):__quickSort(arr, 0, n - 1)def __partition2(arr, l, r):swap(arr, l, random.randint(l, r))temp = arr[l]i = l + 1j = rwhile True:while (i <= r and arr[i] < temp):i += 1while (j >= l + 1 and arr[j] > temp):j -= 1if (j < i):breakswap(arr, j, i)i += 1j -= 1# temp所在的位置是<=temp的一段 因此需要将其与j交换swap(arr, l, j)return jdef __quickSort2(arr, l, r):if (r - l) <= 15:insertionSort4Ms(arr, l, r)returnp = __partition2(arr, l, r)__quickSort2(arr, l, p - 1)__quickSort2(arr, p + 1, r)# 二路快排 将=temp的元素分散到两个集合中,避免平衡树不平衡
def quickSort2(arr, n):__quickSort2(arr, 0, n - 1)def __partition3Ways(arr, l, r):swap(arr, l, random.randint(l, r))temp = arr[l]lt = l  # arr[l+1...lt] < tempgt = r + 1  # arr[gt...r] > tempi = l + 1  # arr[lt+1...i] == tempwhile (i < gt):# i==gt时表示已经比较结束if (arr[i] < temp):swap(arr, i, lt + 1)lt += 1i += 1elif (arr[i] > temp):swap(arr, i, gt - 1)gt -= 1else:  # arr[i] == tempi += 1swap(arr, l, lt)return lt, gtdef __quickSort3Ways(arr, l, r):if (r - l) <= 15:insertionSort4Ms(arr, l, r)returnlt, gt = __partition3Ways(arr, l, r)__quickSort3Ways(arr, l, lt - 1)__quickSort3Ways(arr, gt, r)def quickSort3Ways(arr, n):__quickSort3Ways(arr, 0, n-1)if __name__ == '__main__':n = 100000start = 0end = 10000arr = genNearlyOrderArray(n, swapTimes=100)arr = genRandomArray(n, start, end)arr2 = arr.copy()arr3 = arr.copy()arr4 = arr.copy()aTestSort(mergeSort, arr, n)# aTestSort(quickSort, arr2, n)aTestSort(quickSort2, arr3, n)aTestSort(quickSort3Ways, arr4, n)

归并排序、快速排序、二路快排、三路快排python实现相关推荐

  1. 快速排序 详解(快速排序 双路快排 三路快排)

    注:内容,图片来自于慕课网liuyubobobo老师的课程.  官方代码链接:https://github.com/liuyubobobo/Play-with-Algorithms 快速排序 快速排序 ...

  2. 分治法:快速排序,3种划分方式,随机化快排,快排快,还是归并排序快?

    快速排序不同于之前了解的分治,他是通过一系列操作划分得到子问题,不同之前的划分子问题很简单,划分子问题的过程也是解决问题的过程 我们通常划分子问题尽量保持均衡,而快排缺无法保持均衡 快排第一种划分子问 ...

  3. java三路快排,java二路快排很慢

    老师,以下是我二路快排的java代码 public class quickSortTwoway { public quickSortTwoway() {}; public static void qu ...

  4. 快速排序—三路快排 vs 双基准

    快速排序被公认为是本世纪最重要的算法之一,这已经不是什么新闻了.对很多语言来说是实际系统排序,包括在Java中的Arrays.sort. 那么快速排序有什么新进展呢? 好吧,就像我刚才提到的那样(Ja ...

  5. 三路快排算法加强版(三路快排的再次改进)

    :不要忘记初心哈 :) 理论依据 快排算法的缺陷及其逐一改进 三路快排尽可能三等份划分区间 通过待排元素的区间长度划分? 通过待排元素的最值之差划分? 直接使用待排元素的最大值划分? 实验数据 大范围 ...

  6. LeetCode 75. Sort Colors (python一次遍历,模拟三路快排)

    LeetCode 75. Sort Colors (python一次遍历,模拟三路快排) 题目分析: 本题需要实现数字只包含0,1,2的排序,并且要求一次遍历. 由于只用把数字隔离开,很容易想到快排的 ...

  7. LeetCode--75.颜色分类(三路快排,计数排序)

    颜色分类(C) 1. 题目描述 2. 题目解析 3. C语言实现 3.1 三路快排法 3.2 计数排序法 1. 题目描述 难度:中等 2. 题目解析 这道题需要注意一下几点: 原地进行排序,不可以另外 ...

  8. 八大排序算法之快速排序(上篇)(未经优化的快排)

    目录 一.关于快速排序的总体算法思想 1.冒泡排序(交换排序) (以排升序为例) 2.快速排序的总体思想简介(以排升序为例) 二.快速排序单趟排序的算法接口设计(以排升序为例) 单趟排序实现的方法一: ...

  9. c语言寻找大富翁,PTA 7-38 寻找大富翁(25 分)解法(C/C++)暴力快排/精准堆排 解法...

    7-38 寻找大富翁 (25分) 胡润研究院的调查显示,截至2017年底,中国个人资产超过1亿元的高净值人群达15万人.假设给出N个人的个人资产值,请快速找出资产排前M位的大富翁. 输入格式: 输入首 ...

最新文章

  1. 电脑雕刻教程_理性看待手工雕刻和电脑雕刻,手工并不代表精品,电脑雕刻也不代表战五渣...
  2. mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)
  3. k8s使用kube-router网络插件并监控流量状态
  4. 区块链BaaS云服务(14)华大BGI区块链“Baas接口“
  5. 解决svn中文乱码的问题
  6. 编程语言API性能大比拼
  7. Excel VBA 处理图形图表详解
  8. semantic ui中文文档_Vuetify-广受欢迎的Material风格的开源UI框架
  9. adb命令查看手机电量_desired Capabilities和aapt命令查看手机包信息
  10. 将数据库表中的数据读出以xml的形式下载到手机端
  11. 上海译文公布2019年“新书目录” 名家名译作品结集出版
  12. 通过PyMuPDF编写增值税发票多PDF文件合并工具
  13. Radon变换理论介绍
  14. COMSOL光学仿真专题案例展示
  15. pygame UI 框架
  16. hive查看一张表的分区字段_Hive表分区与索引
  17. HEVC/H.265理论知识(2)——profile、level、tier
  18. nginx fastcgi_buffers设置
  19. navigationController中navigationBar 的设置
  20. MDT CustomSettings.ini Tips Tricks

热门文章

  1. html中加艺术字体,CSS实现漂亮的大标题文字效果
  2. 三星s6 android 5.1.1,或开放特性 三星S6欲推安卓5.1.1
  3. 2019华北五省计算机应用大赛官网,我院师生出战2019华北五省(市、自治区)及港澳台大学生计算机应用大赛荣获佳绩...
  4. Neo4j图数据库简介和底层原理
  5. 树莓派环境搭建(远程桌面、免驱摄像头、tensorflow)总结2018
  6. Allegro 172版本自动放置层叠
  7. 去除数组中的重复的值 C#
  8. js 去除下拉框重复值
  9. gray morphology basic operation
  10. Pr:更改剪辑的速度和持续时间