常见算法排序

常见排序归类

直接插入排序

时间复杂度:O(n²)
空间复杂度:O(1)
稳定性:稳定
算法思想:假设待排序的数据是数组A[1….n]。初始时,A[1]自成1个有序区,无序区为A[2….n]。在排序的过程中,依次将A[i] (i=2,3,….,n)从后往前插入到前面已排好序的子数组A[1,…,i-1]中的适当位置,当所有的A[i] 插入完毕,数组A中就包含了已排好序的输出序列。

def insert_sort(array):  # 定义直接插入排序的函数,将需要排序的数组作为形参
    for i in range(len(array)):  # 从头依次循环,并取循环坐标作为下一循环的节点
        for j in range(i):  # 从头开始,循环到第一循环循环到的数为止
            if array[i] > array[j]:  # 判断第一循环坐标的值是否大于第二循环坐标的值
                array.insert(j, array.pop(i))  # 判断结果为真则将值小的数置前
    return array  # 返回排好序之后的数组

希尔排序
时间复杂度:O(n)
空间复杂度:O(n√n)
稳定性:不稳定
算法思想:希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。

def shell_sort(array):
    gap = len(array)  # 设置增量
    while gap > 1:
        gap = gap // 2  # 选择增量,当所有的数被分为一组的时候即退出循环
        for i in range(gap, len(array)):  # 分组
            for j in range(i % gap, i, gap):  # 设置增量为步进,实现比较每组数大小的效果
                if array[i] < array[j]:  # 判断后将数值小的数组元素置前
                    array[i], array[j] = array[j], array[i]
    return array

简单选择排序
时间复杂度:O(n²)
空间复杂度:O(1)
稳定性:不稳定
算法思想:每一趟从待排序的数据元素中选择最小(或最大)的一个元素作为首元素,直到所有元素排完为止,简单选择排序是不稳定排序。

def select_sort(array):
    for i in range(len(array)):  # 每取一个值,可以看做是一趟
        x = i  # min index
        for j in range(i, len(array)):  # 遍历数组,与取出的元素进行比较
            if array[j] < array[x]:  # 取当前趟次最小元素,置于已经遍历过的数据之前
                x = j
        array[i], array[x] = array[x], array[i]
    return array

堆排序
时间复杂度:O(nlog₂n)
空间复杂度:O(1)
稳定性:不稳定
算法思想:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

def heap_sort(array):
    def heap_adjust(parent):  # 构造初始堆并比较近似完全二叉树中节点的值
        child = 2 * parent + 1  # 左孩子节点
        while child < len(heap):
            if child + 1 < len(heap):
                if heap[child + 1] > heap[child]:
                    child += 1  # 右孩子节点
            if heap[parent] >= heap[child]:  # 父节点大于右孩子节点便结束循环
                break
            heap[parent], heap[child] = heap[child], heap[parent]  # 交换左孩子节点与父节点的值,使大数后沉

            parent, child = child, 2 * child + 1

    heap, array = array.copy(), []
    for i in range(len(heap) // 2, -1, -1):
        heap_adjust(i)
    while len(heap) != 0:  # 使所有的数都经过比较
        heap[0], heap[-1] = heap[-1], heap[0]
        array.insert(0, heap.pop())
        heap_adjust(0)
    return array

https://blog.csdn.net/MoreWindows/article/details/6709644
http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
https://www.cnblogs.com/chengxiao/p/6129630.html


http://images.cnblogs.com/cnblogs_com/kkun/201111/201111301912294099.gif
冒泡排序
时间复杂度:O(n²)
空间复杂度:O(1)
稳定性:稳定
算法思想:对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。

def bubble_sort(array):
    for i in range(len(array)):
        for j in range(i, len(array)):
            if array[i] > array[j]:  # 若前面的数大于后面的数,则交换位置
                array[i], array[j] = array[j], array[i]
    return array

快速排序
时间复杂度:O(nlog₂n)
空间复杂度:O(nlog₂n)
稳定性:不稳定
算法思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

def quick_sort(array):
    def recursive(begin, end):
        if begin > end:
            return
        l, r = begin, end
        pivot = array[l]  # 定义标准,也就是本次执行结束之后找到自己位置的那个数
        while l < r:  # 利用while循环从开始到结尾依次与标准比较
            while l < r and array[r] > pivot:  # 比标准大的数,放到右边
                r -= 1
            while l < r and array[l] <= pivot:  # 比标准小的数,放到左边
                l += 1
            array[l], array[r] = array[r], array[l]  # 若不满足上述条件,左右调换
        array[l], array[begin] = pivot, array[l]  # 标准找到自己位置
        recursive(begin, l - 1)  # 左边调用,即:对比已经找到位置的数小的数进行排序
        recursive(r + 1, end)  # 右边调用,即:对比已经找到位置的数大的数进行排序

    recursive(0, len(array) - 1)  # 调用一次方法,一个数找到正确位置,下次参与排序的数-1
    return array

http://www.cnblogs.com/foreverking/articles/2234225.html


归并排序
时间复杂度:O(nlog₂n)
空间复杂度:O(1)
稳定性:稳定
算法思想:是创建在归并操作上的一种有效的排序算法,效率为O(n log n)。1945年由约翰·冯·诺伊曼首次提出。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。(先分后治再合并)

def merge_sort(array):
    def merge_arr(arr_l, arr_r):  # 先治后合
        array = []
        while len(arr_l) and len(arr_r):  # 治
            if arr_l[0] <= arr_r[0]:  # 右边的组数大,就添加左边的数到下一组
                array.append(arr_l.pop(0))  # 判断一个,取出一个,直到全部取完
            elif arr_l[0] > arr_r[0]:  # 左边的组数大,就添加右边的数到下一组
                array.append(arr_r.pop(0))
        if len(arr_l) != 0:  # 合
            array += arr_l  # 合左边
        elif len(arr_r) != 0:
            array += arr_r  # 合右边
        return array

    def recursive(array):  # 分
        if len(array) == 1:  # 分到最小单位
            return array
        mid = len(array) // 2  # 对二取整,切片划分数组
        arr_l = recursive(array[:mid])
        arr_r = recursive(array[mid:])
        return merge_arr(arr_l, arr_r)  # 一分为二

    return recursive(array)

https://www.cnblogs.com/chengxiao/p/6194356.html


基数排序
时间复杂度:O(d(r+n))
空间复杂度:O(rd+n)
稳定性:稳定
算法思想:将整数按位数切割成不同的数字,然后按每个位数分别比较。

def radix_sort(array):
    bucket, digit = [[]], 0  # 初始化桶数组和数位控制
    while len(bucket[0]) != len(array):  # 判断是否将所有位数取出
        bucket = [[], [], [], [], [], [], [], [], [], []]  # 设置桶数组
        for i in range(len(array)):
            num = (array[i] // 10 ** digit) % 10  # 取当前位数
            bucket[num].append(array[i])  # 放入相应的桶中
        array.clear()  # 清楚当前数据
        for i in range(len(bucket)):
            array += bucket[i]  # 将排好序的桶数组添加进数组
        digit += 1  # 数位控制
    return array

https://www.cnblogs.com/skywang12345/p/3603669.html


算法执行时间
算法速度比较
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容

  • 概述 因为健忘,加上对各种排序算法理解不深刻,过段时间面对排序就蒙了。所以决定对我们常见的这几种排序算法进行统一总...
    清风之心阅读 696评论 0 1
  • 概述排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的...
    Luc_阅读 2,270评论 0 35
  • 母亲61岁了,除了有点轻微高血压,身体还一直不错,没什么毛病,因为她心态好,性格耿直,从不与别人争什么,做着力所能...
    追逐晨风阅读 101评论 0 0
  • 我想知道 没有智能手机 会不会就没有股灾 当然也没有 地球上各个旮旯 发生的天灾 至少我不会 第一时间 伤心流泪
    第一闲人阅读 153评论 1 1
  • 最近生活平静了许多,近一个月也许发生了很多改变,从一个朝九晚五的上班一族,变成了整天在工地打转的无编制人员,从一...
    那年我19阅读 177评论 1 0