python实现八大常见排序算法

常见的排序算法

冒泡排序

每次比较相邻两个数的大小,如果不是预期排序就交换顺序。

import random

def bubble_sort(blist):
    list_len = len(blist)
    for i in range(list_len):
        for j in range(list_len - 1):
            if blist[j] > blist[j+1]:
                blist[j], blist[j+1] = blist[j+1], blist[j]

if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    bubble_sort(ls)
    print(ls)

排序结果

#数据随机生成
[100, 876, 270, 434, 616, 175, 334, 791, 22, 626, 955, 907, 538, 726, 515, 455, 996, 1000, 294, 795, 356, 722, 797, 719, 87, 299, 990, 953, 823, 534, 790, 585, 764, 306, 391, 248, 75, 142, 218, 120, 867, 151, 885, 437, 871, 927, 637, 346, 93, 476]
[22, 75, 87, 93, 100, 120, 142, 151, 175, 218, 248, 270, 294, 299, 306, 334, 346, 356, 391, 434, 437, 455, 476, 515, 534, 538, 585, 616, 626, 637, 719, 722, 726, 764, 790, 791, 795, 797, 823, 867, 871, 876, 885, 907, 927, 953, 955, 990, 996, 1000]

选择排序

第一轮的时候,所有的元素都和第一个元素进行比较,如果比第一个元素小,就和第一个元素进行交换,在这轮比较完后,就找到了最小的元素;第二轮的时候所有的元素都和第二个元素进行比较找出第二个位置的元素,以此类推。

import random

def select_sort(slist):
    list_len = len(slist)
    for i in range(list_len):
        for j in range(i + 1, list_len):
            if slist[i] > slist[j]:
                slist[i], slist[j] = slist[j], slist[i]
                
if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    select_sort(ls)
    print(ls)

排序结果

#数据随机生成
[612, 148, 571, 433, 724, 396, 720, 703, 853, 486, 991, 856, 800, 723, 911, 848, 873, 611, 845, 268, 821, 847, 149, 372, 686, 801, 762, 720, 279, 272, 820, 895, 629, 195, 777, 908, 625, 803, 503, 13, 197, 422, 961, 814, 327, 598, 831, 957, 682, 295]
[13, 148, 149, 195, 197, 268, 272, 279, 295, 327, 372, 396, 422, 433, 486, 503, 571, 598, 611, 612, 625, 629, 682, 686, 703, 720, 720, 723, 724, 762, 777, 800, 801, 803, 814, 820, 821, 831, 845, 847, 848, 853, 856, 873, 895, 908, 911, 957, 961, 991]

插入排序

将序列分为已排序序列和未排序序列,每次从未排序序列中取出一个数,插入到已排序的序列中。

import random

def insert_sort(ilist):
    list_len = len(ilist)
    for i in range(1, list_len):
        num = ilist.pop(i)
        for j in range(i-1, -1, -1):
            if num > ilist[j]:
                ilist.insert(j+1, num)
                break
            if j == 0:
                ilist.insert(0, num)

if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    insert_sort(ls)
    print(ls)

排序结果

#数据随机生成
[897, 349, 40, 577, 678, 70, 809, 779, 16, 779, 371, 261, 618, 319, 895, 455, 521, 664, 469, 380, 149, 735, 422, 604, 639, 24, 112, 997, 5, 643, 12, 854, 315,
207, 225, 553, 290, 527, 524, 797, 880, 979, 810, 35, 341, 328, 617, 410, 869, 351]
[5, 12, 16, 24, 35, 40, 70, 112, 149, 207, 225, 261, 290, 315, 319, 328, 341, 349, 351, 371, 380, 410, 422, 455, 469, 521, 524, 527, 553, 577, 604, 617, 618, 639, 643, 664, 678, 735, 779, 779, 797, 809, 810, 854, 869, 880, 895, 897, 979, 997]

希尔排序

将数组列在一个表中并对列分别进行插入排序,重复这过程,
每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。

import random 

def shell_sort(slist):
    list_len = len(slist)
    gap = list_len // 2
    while gap:
        for i in range(gap, list_len):
            tmp = i
            for j in range(i, -1, -gap):
                if slist[tmp] < slist[j]:
                    slist[tmp], slist[j] = slist[j], slist[tmp]
                    tmp = j
        gap = gap // 2
                
if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    shell_sort(ls)
    print(ls)

排序结果

#数据随机生成
[54, 410, 371, 988, 276, 194, 101, 446, 497, 224, 616, 495, 652, 146, 539, 367, 515, 278, 201, 142, 793, 718, 700, 803, 523, 873, 288, 612, 712, 283, 24, 327,
446, 609, 934, 283, 367, 502, 792, 877, 726, 68, 150, 406, 406, 921, 499, 778, 24, 977]
[24, 24, 54, 68, 101, 142, 146, 150, 194, 201, 224, 276, 278, 283, 283, 288, 327, 367, 367, 371, 406, 406, 410, 446, 446, 495, 497, 499, 502, 515, 523, 539, 609, 612, 616, 652, 700, 712, 718, 726, 778, 792, 793, 803, 873, 877, 921, 934, 977, 988]

归并排序

归并排序是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,再合并数组。
将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,取较小的数,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。

import random 

def merge_sort(mlist):
    def merge_divide(mlist, left, right):
        if left >= right:
            return
        mid = (left+right)//2
        merge_divide(mlist, left, mid)
        merge_divide(mlist, mid+1, right)
        merge_conquer(mlist, left, mid, right)

    def merge_conquer(mlist, left, mid, right):
        res = []
        left_pos = left
        right_pos = mid+1
        while left_pos <= mid and right_pos <= right:
            if mlist[left_pos] <= mlist[right_pos]:
                res.append(mlist[left_pos])
                left_pos += 1
            else:
                res.append(mlist[right_pos])
                right_pos += 1             
        while left_pos <= mid:
            res.append(mlist[left_pos])
            left_pos += 1
        while right_pos <= right:
            res.append(mlist[right_pos])
            right_pos += 1
        for i in range(left, right+1):
            mlist[i] = res[i-left]
    merge_divide(mlist, 0, len(mlist)-1)
                
if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    merge_sort(ls)
    print(ls)

排序结果

#数据随机生成
[457, 830, 429, 160, 932, 584, 394, 740, 834, 674, 201, 224, 475, 184, 326, 849, 607, 29, 805, 953, 530, 657, 224, 918, 485, 646, 1000, 623, 404, 733, 478, 386, 999, 856, 500, 647, 65, 39, 389, 60, 292, 812, 564, 502, 728, 486, 907, 934, 97, 324]
[29, 39, 60, 65, 97, 160, 184, 201, 224, 224, 292, 324, 326, 386, 389, 394, 404, 429, 457, 475, 478, 485, 486, 500, 502, 530, 564, 584, 607, 623, 646, 647, 657, 674, 728, 733, 740, 805, 812, 830, 834, 849, 856, 907, 918, 932, 934, 953, 999, 1000]

快速排序

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

import random

def quick_sort(qlist):
    if qlist == []:
        return []
    else :
        q = qlist[0]
        bigger_list = quick_sort([num for num in qlist[1:] if num >= q])
        less_list = quick_sort([num for num in qlist[1:] if num < q])
    return less_list + [q] + bigger_list

if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    ls = quick_sort(ls)
    print(ls)

排序结果

#数据随机生成
[86, 710, 253, 892, 951, 430, 325, 621, 95, 290, 89, 952, 734, 711, 280, 84, 834, 467, 862, 731, 744, 388, 577, 427, 89, 500, 803, 279, 461, 669, 951, 602, 936, 984, 873, 440, 880, 897, 172, 722, 887, 61, 324, 263, 369, 979, 647, 453, 54, 626]
[54, 61, 84, 86, 89, 89, 95, 172, 253, 263, 279, 280, 290, 324, 325, 369, 388, 427, 430, 440, 453, 461, 467, 500, 577, 602, 621, 626, 647, 669, 710, 711, 722,
731, 734, 744, 803, 834, 862, 873, 880, 887, 892, 897, 936, 951, 951, 952, 979, 984]

计数排序

计数排序用待排序的数值作为计数数组(列表)的下标,统计每个数值的个数,然后依次输出即可。

import random 

def count_sort(clist):
    clist_len = len(clist)
    cnt = [0]*(max(clist)+1)
    tmp = []*clist_len
    for i in range(clist_len):
        cnt[clist[i]] += 1
    for i in range(len(cnt)):
        for _ in range(cnt[i]):
            tmp.append(i)

    return tmp
                
if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    ls = count_sort(ls)
    print(ls)

排序结果

#数据随机生成
[490, 67, 157, 316, 869, 497, 172, 761, 107, 20, 968, 371, 690, 431, 82, 886, 84, 267, 496, 913, 681, 451, 846, 245, 641, 700, 338, 164, 925, 938, 348, 760, 277, 639, 753, 338, 700, 100, 192, 626, 809, 400, 248, 648, 673, 845, 430, 748, 315, 339]
[20, 67, 82, 84, 100, 107, 157, 164, 172, 192, 245, 248, 267, 277, 315, 316, 338, 338, 339, 348, 371, 400, 430, 431, 451, 490, 496, 497, 626, 639, 641, 648, 673, 681, 690, 700, 700, 748, 753, 760, 761, 809, 845, 846, 869, 886, 913, 925, 938, 968]

基数排序

每个数从低位往高位取,每次取一位数,并对所有数的同一位计数排序。

import math
import random 

def radix_sort(mlist):   
    def get_bit(num, index):
        return num//(int(math.pow(10, index)))%10

    max_num = max(mlist)
    max_bit = int(math.log10(max_num))+1
    for i in range(0, max_bit):
        res = []
        radix = [[] for _ in range(10)]
        for num in mlist:
            radix[get_bit(num, i)].append(num)
        for j in range(10):
            res += radix[j]
        mlist = res
    return mlist


if __name__ == '__main__':
    ls = [random.randint(0, 1000) for i in range(50)]
    print(ls)
    ls = radix_sort(ls)
    print(ls)

排序结果

#数据随机生成
[873, 153, 619, 43, 706, 847, 751, 860, 363, 234, 561, 440, 591, 726, 523, 446, 769, 38, 674, 261, 691, 827, 455, 453, 332, 350, 53, 868, 370, 788, 834, 900, 804, 99, 568, 223, 127, 191, 618, 264, 99, 693, 363, 691, 268, 844, 300, 356, 808, 642]
[38, 43, 53, 99, 99, 127, 153, 191, 223, 234, 261, 264, 268, 300, 332, 350, 356, 363, 363, 370, 440, 446, 453, 455, 523, 561, 568, 591, 618, 619, 642, 674, 691, 691, 693, 706, 726, 751, 769, 788, 804, 808, 827, 834, 844, 847, 860, 868, 873, 900]
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值