排序算法(2)

简介: 排序算法(2)

概要

接上回

在上篇说过经典的排序算法,有冒泡,插入,选择;归并,快排。其中讲了冒泡,插入,选择;这一回写归并和快排。

原理及实现

原理是很好玩的,如果不喜欢,先记住,总有一天会用得上的。

原理挺有意思的,喜欢就去研究,不喜欢就记住一些常用的,以备不时之需。先聊聊归并吧。

归并排序

本来想找个定义,看了下维基百科,也不是很满意的概念,如下:

定义

归并排序(英语:Merge sort,或mergesort),是建立在归并操作上的一种有效的排序算法,效率为𝑂(𝑛log𝑛)(大O符号)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。

定义是这样的,怎么理解呢?采用分治递归,意思就是先平均分成2份,然后比较排序;递归这种操作,就是将2份中任何一份继续采用分治法(分治法这里不细聊,以后会写文章的),分成2份,直到不能再分为止;

性能

  1. 归并排序是稳定的排序算法;数组长度就那么长,一直在分割,然后继续分割直到不能再分,然后采用合并数组;
  2. 时间复杂度:O(nlogn)
  3. 空间复杂度:O(nlogn)

代码Python

dfrom typing import List
def merge_sort(a: List[int]):
    merge_sort_between(a, 0, len(a) - 1)
def merge_sort_between(a: List[int], low: int, high: int):
    # The indices are inclusive for both low and high.
    if low < high:
        mid = low + (high - low) // 2
        merge_sort_between(a, low, mid)
        merge_sort_between(a, mid + 1, high)
        merge(a, low, mid, high)
def merge(a: List[int], low: int, mid: int, high: int):
    # a[low:mid], a[mid+1, high] are sorted.
    i, j = low, mid + 1
    tmp = []
    while i <= mid and j <= high:
        if a[i] <= a[j]:
            tmp.append(a[i])
            i += 1
        else:
            tmp.append(a[j])
            j += 1
    start = i if i <= mid else j
    end = mid if i <= mid else high
    tmp.extend(a[start:end + 1])
    a[low:high + 1] = tmp

快速排序

归并说完了,来看看快排。定义如下:

定义

快速排序(英语:Quicksort),又称分区交换排序(partition-exchange sort),是一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序𝑛个项目要𝑂(𝑛log𝑛)(大O符号)次比较。在最坏状况下则需要𝑂(n 2 n^2n2)次比较,但这种状况并不常见。事实上,快速排序Θ(𝑛log𝑛)通常明显比其他算法更快,因为它的内部循环可以在大部分的架构上很有效率地达成。

按照定义,对一定长度的数据,选一个基准值,然后所有数据一个一个跟基准值比较,然后交互i,j的位置。还是分治和递归的思想,一直这么分,partion。

接下来看看代码,如下:

代码

from typing import List
import random
def quick_sort(a: List[int]):
    quick_sort_between(a, 0, len(a) - 1)
def quick_sort_between(a: List[int], low: int, high: int):
    if low < high:
        # get a random position as the pivot
        k = random.randint(low, high)
        a[low], a[k] = a[k], a[low]
        m = partition(a, low, high)  # a[m] is in final position
        quick_sort_between(a, low, m - 1)
        quick_sort_between(a, m + 1, high)
def partition(a: List[int], low: int, high: int):
    pivot, j = a[low], low
    for i in range(low + 1, high + 1):
        if a[i] <= pivot:
            j += 1
            a[j], a[i] = a[i], a[j]  # swap
    a[low], a[j] = a[j], a[low]
    return j

小结

学习总结

归并,排序都采用了分治的思想。时间复杂度归并O(nlogn),空间复杂度归并的比较大,达到O(n);快排时间复杂度O(nlogn),快排极端情况达到O(n 2 n^2n2),但是概率很小,而且可以通过合理的选用基准值来避免,适用范围较广。

相关文章
|
7月前
|
搜索推荐
简单的排序算法
简单的排序算法
56 1
|
5月前
|
搜索推荐 算法
排序算法总结
排序算法总结
37 11
|
6月前
|
搜索推荐 算法 Python
排序算法1
排序算法1
|
7月前
|
搜索推荐 算法 数据处理
C++中的排序算法
C++中的排序算法
59 0
|
搜索推荐 算法 Shell
排序算法
排序算法
42 1
|
7月前
|
存储 搜索推荐 算法
常见排序算法实现(一)
常见排序算法实现(一)
80 0
|
7月前
|
搜索推荐 算法
常见排序算法实现(二)
常见排序算法实现(二)
59 0
|
搜索推荐 算法
14 排序算法
14 排序算法
33 0
|
算法 搜索推荐 Java
常见排序算法详解(1)
前言 排序是我们在日常生活和工作中常见的一种操作。在计算机科学中,排序算法就是将一串或一组数据按照特定的顺序进行排列的算法。这些顺序可能是数字的升序或降序,也可能是字母或字词的字母顺序等。我们将探讨几种不同的排序算法,包括他们的原理、优缺点以及代码实现。
142 0
|
搜索推荐 Java
常见的10种排序算法
常见的10种排序算法
113 0