常用排序算法

排序算法

1、冒泡排序

时间复杂度O(N^2)

def bubblesort(nums):
    if len(nums) < 2:   #数组长度小于2没必要排序
        return nums
    for i in range(len(nums)):  #外层遍历,遍历整个数据长度,循环一次确定一个最大的数字
        for j in range(1, len(nums) - i):   #内层遍历,遍历数组1到数组长度减外层遍历个数
            if nums[j] < nums[j - 1]:   #后面数字比前面小交换位置
                temp = nums[j]
                nums[j] = nums[j - 1]
                nums[j - 1] = temp
        return nums

2、选择排序

时间复杂度O(N^2)

def selectionsort(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return nums
    for i in range(len(nums)):
        minnum = i
        for j in range(i + 1, len(nums)):  # 从剩下的数组长度减i个数中选择最小的与i位置的数交换
            minnum = j if nums[j] < nums[minnum] else minnum
        temp = nums[minnum]
        nums[minnum] = nums[i]
        nums[i] = temp
    return nums

3、插入排序

时间复杂度O(N^2),跟数据情况有关系,最好O(N)

def insertionsort(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return nums
    for i in range(1, len(nums)):
        for j in range(i - 1, -1, -1):  # i与i位置之前的有序数组比较,i小于之前的插入
            if nums[i] < nums[j]:
                temp = nums[j]
                nums[j] = nums[i]
                nums[i] = temp
                i -= 1
            else:
                break
    print(nums)
    return nums

4、归并排序

时间复杂度O(N*logN)

def mergesort(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return nums
    sortprocess(nums, 0, len(nums) - 1) #归并排序输入左右端点
    return nums


def sortprocess(nums, L, R):
    if L == R:
        return
    mid = L + (R - L) // 2  #左右端点一分为二,分别进行子过程排序
    print('mid', mid)
    sortprocess(nums, L, mid)
    sortprocess(nums, mid + 1, R)
    merge(nums, L, R, mid)


def merge(nums, L, R, mid): #对分成的两个有序数组进行融合
    print(L, R, mid)
    help = [0] * (R - L + 1)
    i = 0
    left = L
    right = mid + 1
    while left <= mid and right <= R:
        if nums[left] < nums[right]:
            help[i] = nums[left]
            left += 1
        else:
            help[i] = nums[right]
            right += 1
        i += 1
    while left <= mid:
        help[i] = nums[left]
        left += 1
        i += 1
    while right <= R:
        help[i] = nums[right]
        right += 1
        i += 1
    for i in range(i):
        nums[i + L] = help[i]

归并排序应用:逆序对问题

    在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。
示例 1:
输入: [7,5,6,4]
输出: 5

def reversepairs(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return 0
    return sortprocess(nums, 0, len(nums) - 1)  # 返回总的逆序对


def sortprocess(nums, L, R):
    if L == R:
        return 0
    mid = L + (R - L) // 2  # 左右端点一分为二,分别进行子过程排序
    print('mid', mid)
    return sortprocess(nums, L, mid) + sortprocess(nums, mid + 1, R) + merge(nums, L, R, mid)


def merge(nums, L, R, mid):  # 对分成的两个有序数组进行融合
    print(L, R, mid)
    help = [0] * (R - L + 1)
    i = 0
    left = L
    right = mid + 1
    res = 0
    while left <= mid and right <= R:
        if nums[left] > nums[right]:
            help[i] = nums[left]
            left += 1
            res += R - right + 1    #记录这一轮中,左侧数比右侧大的数目
        else:
            help[i] = nums[right]
            right += 1
        i += 1
    while left <= mid:
        help[i] = nums[left]
        left += 1
        i += 1
    while right <= R:
        help[i] = nums[right]
        right += 1
        i += 1
    for i in range(i):
        nums[i + L] = help[i]
    return res

5、快速排序

时间复杂度O(NlogN)

def quicksort(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return nums
    quick(nums, 0, len(nums) - 1)
    return nums


def quick(nums, l, r):
    if l < r:
        less, more = partition(nums, l, r)
        quick(nums, l, less - 1)
        quick(nums, more + 1, r)


def partition(nums, l, r):
    aim = nums[l]
    less = l
    more = r
    cur = l
    while cur <= more:
        if nums[cur] < aim:
            temp = nums[cur]
            nums[cur] = nums[less]
            nums[less] = temp
            cur += 1
            less += 1
        elif nums[cur] > aim:
            temp = nums[cur]
            nums[cur] = nums[more]
            nums[more] = temp
            more -= 1
        else:
            cur += 1
    return less, more

6、堆排序

时间复杂度O(NlogN)

def heapsort(nums):
    if len(nums) < 2:  # 数组长度小于2没必要排序
        return nums
    for i in range(len(nums)):
        heapinsert(nums, i)
    heapsize = len(nums)
    while heapsize > 0:
        temp = nums[0]
        nums[0] = nums[heapsize - 1]
        nums[heapsize - 1] = temp
        heapsize -= 1
        heapify(nums, 0, heapsize)
    return nums


def heapinsert(nums, index):
    while index > 0 and nums[index] > nums[(index - 1) // 2]:
        temp = nums[index]
        nums[index] = nums[(index - 1) // 2]
        nums[(index - 1) // 2] = temp
        index = (index - 1) // 2


def heapify(nums, index, heapsize):
    left = 2 * index + 1
    while left < heapsize:
        large = left + 1 if left + 1 < heapsize and nums[left + 1] > nums[left] else left
        large = large if nums[large] > nums[index] else index
        if large == index:
            break
        temp = nums[index]
        nums[index] = nums[large]
        nums[large] = temp
        index = large
        left = 2 * index + 1

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