python实现几种常见的排序算法

以下排序算法均按照从小到大排序N个元素:

1、冒泡排序

基本思想:
遍历元素列表,比较相邻的元素,如果第一个比第二个大,则交换其位置,经过第一轮比较,最大的元素将恰好被放置到最后一个;
第二轮不再比较最后的元素,只比较前面的N-1个元素,则经过第二轮比较之后,我们可以确定第二大的元素;
依次类推,第i轮比较能够确定第i大的元素,可知经过N-1轮比较后我们能够确定所有元素的位置(为什么不是N轮比较?——因为前N-1个大的元素确定了,还剩最后一个,自然就是最小的,无需再比较)

def bubble_sort(nums):
    if nums is not None:  # 注意判空,不要用=或者!=判空
        for i in range(1, len(nums)):  # 一共进行1到N-1轮比较,N即列表长度len(nums)
            is_sorted = True  # 用来判断是否已经排好序
            for j in range(len(nums) - i):  # 第i轮比较中需要比较第0,1,…,(N-i-1)个元素与其后面一个位置上的元素的大小
                if nums[j] > nums[j + 1]:
                    is_sorted = False  # 如果没有发生交换,则说明已经排好序,无需进行下一轮比较
                    nums[j], nums[j + 1] = nums[j + 1], nums[j]

            if is_sorted:
                break
    return nuts

2、选择排序

基本思想:
遍历元素,记录下最小的元素所在的位置,然后把最小的元素和位置0上的元素互换;
一共进行N-1轮遍历:
第一轮确定第1小的元素,放在位置0;
第二轮确定第2小的元素,放在位置1;x

第i轮确定第i小的元素,放在位置i;
N-1轮遍历之后可以确定所有元素的正确位置。

def select_sort(nums):
    if nums is not None:  # 注意判空

        for i in range(0, len(nums) - 1):  # 一共进行0到N-2共N-1轮选择,N即列表长度len(nums)
            min_index = i  # 先初始化每轮选择中最小的元素的位置为每轮遍历的第一个元素
            for j in range(i + 1, len(nums)):  # 从第一个元素的下一个位置开始与记录的最小元素做比较
                if nums[j] < nums[min_index]:
                    min_index = j

            if i != min_index:
                nums[i], nums[min_index] = nums[min_index], nums[i]

3、快速排序

基本思想:采用分而治之的思想,选取nums中的一个数作为基准点,把要排序的数据分成两部分,一部分比基准点小,一部分比基准点大;
然后再对这两部分数据分别采用分而治之的方法进行排序;
最后再把这几部分数据连接到一起。

def quick_sort(nums):

    if len(nums) <= 1:
        return nums

    pivot = nums[len(nums) // 2]
    left = [x for x in nums if x < pivot]
    middle = [x for x in nums if x == pivot]
    right = [x for x in nums if x > pivot]

    return quick_sort(left) + middle + quick_sort(right)

4、插入排序

基本思想:插入排序的原理类似于打扑克牌,把待排序数据分成两部分,一部分是已排好序的有序数据,一部分是乱序数据,
开始时默认第一个数有序,然后再将后面的数逐个插入,插入操作具体包括:
1、与有序数据比较,确定插入位置,
2、在每次比较中将比待插入数据大的数据后移,给待插入数据腾位置

def insert_sort(nums):
    for i in range(len(nums)):
        preIndex = i-1  # 0到i-1的数据为已经排好序的有序数据
        curnum = nums[i]  # 记录下一个要插入到有序数据中的数

        # 遍历有序数据,找到curnum应插入的位置
        while preIndex >= 0 and nums[preIndex] > curnum:  # 注意不要漏掉preIndex等于0
            nums[preIndex+1] = nums[preIndex]  # 比curnum大的数往后挪
            preIndex -= 1

        nums[preIndex+1] = curnum

    return nums

5、希尔排序

基本思想:希尔排序是直接插入排序的升级版,减少插入排序的移动次数
插入排序在每次插入一个数据的过程中,凑要大量移动数据,

希尔排序将序列按固定间隔划分为多个子序列,在子序列中简单插入排序,先做远距离移动使序列基本有序;
逐渐缩小间隔重复操作,最后间隔为1时即简单插入排序。

def shell_insert(nums, d):
    n = len(nums)
    for i in range(d, n):
        j = i - d
        temp = nums[i]  # 记录要插入的数
        while j >= 0 and nums[j] > temp:  # 从后向前,找到比其小的数的位置
            nums[j + d] = nums[j]  # 向后挪动
            j -= d
        if j != i - d:
            nums[j + d] = temp


def shell_sort(nums):

    n = len(nums)
    if n <= 1:
        return nums
    d = n//2
    while d >= 1:
        shell_insert(nums, d)
        d = d//2
    return nums

6、归并排序

基本思想:归并排序运用分治递归思想:将大问题分为较小的子问题,分而治之;递归调用同样的方法解决子问题。
最终将序列的排序问题分治为一个数的排序问题,关键在于如何将子问题答案合并为问题答案。

两个有序序列合并为一个有序序列,借助一个暂存数组(列表),两个序列元素依次比较填入暂存列表,形成一个有序序列。
归并排序划分子问题采用二分法,共需O(logn)次划分,当然需要相当次合并;每次合并遍历比较O(n)。时间复杂度O(nlogn)。

def merge_sort(nums):
    import math
    if len(nums) < 2:
        return nums
    middle = math.floor(len(nums)/2)
    left, right = nums[0:middle], nums[middle:]
    return merge(merge_sort(left), merge_sort(right))

def merge(left, right):
    result = []
    while left and right:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))

    while left:
        result.append(left.pop(0))
    while right:
        result.append(right.pop(0))

    return result

参考学习:
十大排序算法总结Python3实现
python 十大经典排序算法

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

推荐阅读更多精彩内容