python实现八大排序算法及性能分析(比较次数与移动次数分析)

本文通过Python实现直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序和归并排序,并分析各自比较和移动次数。实验数据显示,对于大规模数据,快速排序和堆排序在性能上更优。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Libaray

import numpy as np
import pandas as pd
from tqdm import tqdm

数据生成

test_50000  = np.random.randint(0, 100000, (50000))
print("test_50000, len:%d, test_50000[1]=%d"%(len(test_50000),test_50000[1]))

test_100000  = np.random.randint(0, 200000, (100000))
print("test_100000, len:%d, test_100000[1]=%d"%(len(test_100000),test_100000[1]))

test_250000  = np.random.randint(0, 500000, (250000))
print("test_250000, len:%d, test_250000[1]=%d"%(len(test_250000),test_250000[1]))

test_500000  = np.random.randint(0, 1000000, (500000))
print("test_500000, len:%d, test_500000[1]=%d"%(len(test_500000),test_500000[1]))

test_750000  = np.random.randint(0, 1500000, (750000))
print("test_750000, len:%d, test_750000[1]=%d"%(len(test_750000),test_750000[1]))
test_50000, len:50000, test_50000[1]=9225
test_100000, len:100000, test_100000[1]=11484
test_250000, len:250000, test_250000[1]=162643
test_500000, len:500000, test_500000[1]=348200
test_750000, len:750000, test_750000[1]=1361766

存储数据

test_50000 = pd.DataFrame(test_50000)
test_50000.to_csv("./test_50000.csv", index=False)

test_100000 = pd.DataFrame(test_100000)
test_100000.to_csv("./test_100000.csv", index=False)

test_250000 = pd.DataFrame(test_250000)
test_250000.to_csv("./test_250000.csv", index=False)

test_500000 = pd.DataFrame(test_500000)
test_500000.to_csv("./test_500000.csv", index=False)

test_750000 = pd.DataFrame(test_750000)
test_750000.to_csv("./test_750000.csv", index=False)

数据格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VdSOdq46-1623653033838)(./img/data.png)]

直接插入排序

每次将一个待排序的记录插入到已排好序的数据区中直到全部插入完为止。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-drhi49uC-1623653033842)(./img/insert_sort.png)]

是稳定的排序。

监视哨的插入排序:

  • 设置监视哨r[0],将待插入记录的值赋给r[0]
  • 设置查找起始位置j
  • 查找:
    • while(r[0].key<r[j-1].key)
    • r[j]=r[0]
  • 监视哨的作用
    • 进入查找循环之前,保存了r[i]的副本,记录后移时不会丢失r[i]的内容。
    • 循环中“监视”下标变量j是否越界。
    • 一旦越界(即j=0),能控制while循环结束。
    • 避免在while循环内每次都要检测j是否越界的问题。
def insert_sort(data):
    compare_count = 0
    move_count = 0
    for k in tqdm(range(1, len(data))):
        cur = data[k]
        j = k
        while j > 0 and data[j - 1] > cur:
            data[j] = data[j - 1]
            compare_count += 1
            move_count += 3
            j -= 1
        compare_count += 1  # 最后一次比较没有进入循环内部
        data[j] = cur
    print("----------------\ncompare_count=%d, move_count=%d"%(compare_count, move_count))
    return data

# eazy_test = [5,3,4,1,2]
# result_insert = insert_sort(eazy_test)
# result_insert

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = insert_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = insert_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = insert_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = insert_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = insert_sort(test_750000)
print("result5_des:",result5[1000:1005])
100%|██████████| 49999/49999 [03:41<00:00, 225.49it/s]
  1%|          | 1101/99999 [00:00<00:09, 10897.23it/s]----------------
compare_count=620412874, move_count=1861088625
result1_des: [2004, 2004, 2006, 2007, 2011]
100%|██████████| 99999/99999 [15:59<00:00, 104.21it/s]
  0%|          | 1116/249999 [00:00<00:22, 11055.26it/s]----------------
compare_count=2503069815, move_count=7508909448
result2_des: [1995, 1995, 1999, 1999, 2002]
 66%|██████▋   | 165679/249999 [44:41<22:44, 61.79it/s]



---------------------------------------------------------------------------

KeyboardInterrupt                         Traceback (most recent call last)

<ipython-input-82-034b75334a44> in <module>
     33 print("result2_des:",result2[1000:1005])
     34 
---> 35 result3 = insert_sort(test_250000)
     36 print("result3_des:",result3[1000:1005])
     37 


<ipython-input-82-034b75334a44> in insert_sort(data)
      6         j = k
      7         while j > 0 and data[j - 1] > cur:
----> 8             data[j] = data[j - 1]
      9             compare_count += 1
     10             move_count += 3


KeyboardInterrupt: 

希尔排序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0HINo3AH-1623653033847)(./img/shell_sort.png)]

shell排序是对位置间隔较大的结点进行比较,则结点一次比较后能跨过较距离,可能提高排序速度。

shell排序是不稳定的排序。

def shell_sort(numberlist):
    compare_count = 0
    move_count = 0
    length = len(numberlist)
    gap = length // 2
    while gap > 0:
        for i in tqdm(range(gap, length)):
            temp = numberlist[i]
            j = i
            while j >= gap and numberlist[j - gap] > temp:
                numberlist[j] = numberlist[j - gap]
                compare_count += 1
                move_count += 3
                j -= gap
            compare_count += 1  # 最后一次比较没有进入循环内部
            numberlist[j] = temp
        gap = gap // 2
    print("----------------\ncompare_count=%d, move_count=%d"%(compare_count, move_count))
    return numberlist

# eazy_test = [5,3,4,1,2]
# result_shell = shell_sort(eazy_test)
# result_shell

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = shell_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = shell_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = shell_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = shell_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = shell_sort(test_750000)
print("result5_des:",result5[1000:1005])
100%|██████████| 25000/25000 [00:00<00:00, 1563055.82it/s]
100%|██████████| 37500/37500 [00:00<00:00, 1171462.41it/s]
100%|██████████| 43750/43750 [00:00<00:00, 857668.74it/s]
100%|██████████| 46875/46875 [00:00<00:00, 821881.39it/s]
100%|██████████| 48438/48438 [00:00<00:00, 550444.87it/s]
100%|██████████| 49219/49219 [00:00<00:00, 756534.86it/s]
100%|██████████| 49610/49610 [00:00<00:00, 604620.15it/s]
100%|██████████| 49805/49805 [00:00<00:00, 754068.41it/s]
100%|██████████| 49903/49903 [00:00<00:00, 445566.34it/s]
100%|██████████| 49952/49952 [00:00<00:00, 402826.08it/s]
100%|██████████| 49976/49976 [00:00<00:00, 657608.04it/s]
100%|██████████| 49988/49988 [00:00<00:00, 504928.19it/s]
100%|██████████| 49994/49994 [00:00<00:00, 568105.56it/s]
100%|██████████| 49997/49997 [00:00<00:00, 684886.37it/s]
100%|██████████| 49999/49999 [00:00<00:00, 480750.38it/s]
100%|██████████| 50000/50000 [00:00<00:00, 1219565.13it/s]
100%|██████████| 75000/75000 [00:00<00:00, 1071612.09it/s]
  0%|          | 0/87500 [00:00<?, ?it/s]----------------
compare_count=1871346, move_count=3514020
result1_des: [2004, 2004, 2006, 2007, 2011]
100%|██████████| 87500/87500 [00:00<00:00, 1005723.56it/s]
100%|██████████| 93750/93750 [00:00<00:00, 738191.20it/s]
100%|██████████| 96875/96875 [00:00<00:00, 601716.04it/s]
100%|██████████| 98438/98438 [00:00<00:00, 489740.19it/s]
100%|██████████| 99219/99219 [00:00<00:00, 740442.59it/s]
100%|██████████| 99610/99610 [00:00<00:00, 547196.10it/s]
100%|██████████| 99805/99805 [00:00<00:00, 792165.09it/s]
100%|██████████| 99903/99903 [00:00<00:00, 440097.63it/s]
100%|██████████| 99952/99952 [00:00<00:00, 396637.03it/s]
100%|██████████| 99976/99976 [00:00<00:00, 414836.23it/s]
100%|██████████| 99988/99988 [00:00<00:00, 534693.72it/s]
100%|██████████| 99994/99994 [00:00<00:00, 574667.84it/s]
100%|██████████| 99997/99997 [00:00<00:00, 644951.58it/s]
100%|██████████| 99999/99999 [00:00<00:00, 469438.28it/s]
100%|██████████| 125000/125000 [00:00<00:00, 992045.29it/s]
  0%|          | 0/187500 [00:00<?, ?it/s]----------------
compare_count=4471802, move_count=8915388
result2_des: [1995, 1995, 1999, 1999, 2002]
100%|██████████| 187500/187500 [00:00<00:00, 848410.97it/s]
100%|██████████| 218750/218750 [00:00<00:00, 739013.12it/s]
100%|██████████| 234375/234375 [00:00<00:00, 781177.49it/s]
100%|██████████| 242188/242188 [00:00<00:00, 584942.57it/s]
100%|██████████| 246094/246094 [00:00<00:00, 711259.33it/s]
100%|██████████| 248047/248047 [00:00<00:00, 501103.72it/s]
100%|██████████| 249024/249024 [00:00<00:00, 406217.06it/s]
100%|██████████| 249512/249512 [00:00<00:00, 710851.08it/s]
100%|██████████| 249756/249756 [00:00<00:00, 416957.26it/s]
100%|██████████| 249878/249878 [00:00<00:00, 427118.00it/s]
100%|██████████| 249939/249939 [00:00<00:00, 422193.40it/s]
100%|██████████| 249970/249970 [00:01<00:00, 182194.32it/s]
100%|██████████| 249985/249985 [00:00<00:00, 528471.63it/s]
100%|██████████| 249993/249993 [00:00<00:00, 591000.20it/s]
100%|██████████| 249997/249997 [00:00<00:00, 690588.10it/s]
100%|██████████| 249999/249999 [00:00<00:00, 856172.68it/s]
100%|██████████| 250000/250000 [00:00<00:00, 1249770.27it/s]----------------
compare_count=12954384, move_count=26863131
result3_des: [1981, 1982, 1983, 1985, 1987]

100%|██████████| 375000/375000 [00:00<00:00, 1179424.50it/s]
100%|██████████| 437500/437500 [00:00<00:00, 1118924.37it/s]
100%|██████████| 468750/468750 [00:00<00:00, 1005819.81it/s]
100%|██████████| 484375/484375 [00:00<00:00, 887130.21it/s]
100%|██████████| 492188/492188 [00:00<00:00, 557406.78it/s]
100%|██████████| 496094/496094 [00:00<00:00, 765577.44it/s]
100%|██████████| 498047/498047 [00:00<00:00, 672130.86it/s]
100%|██████████| 499024/499024 [00:01<00:00, 430933.79it/s]
100%|██████████| 499512/499512 [00:00<00:00, 657293.26it/s]
100%|██████████| 499756/499756 [00:01<00:00, 482389.73it/s]
100%|██████████| 499878/499878 [00:01<00:00, 424593.79it/s]
100%|██████████| 499939/499939 [00:01<00:00, 374421.54it/s]
100%|██████████| 499970/499970 [00:02<00:00, 174144.50it/s]
100%|██████████| 499985/499985 [00:00<00:00, 696358.46it/s]
100%|██████████| 499993/499993 [00:00<00:00, 572704.55it/s]
100%|██████████| 499997/499997 [00:00<00:00, 829182.85it/s]
100%|██████████| 499999/499999 [00:00<00:00, 847393.73it/s]
 30%|██▉       | 111168/375000 [00:00<00:00, 1111222.72it/s]----------------
compare_count=28856913, move_count=61070718
result4_des: [2000, 2001, 2006, 2007, 2013]
100%|██████████| 375000/375000 [00:00<00:00, 1126140.02it/s]
100%|██████████| 562500/562500 [00:00<00:00, 1225396.33it/s]
100%|██████████| 656250/656250 [00:00<00:00, 831746.25it/s]
100%|██████████| 703125/703125 [00:01<00:00, 573977.07it/s]
100%|██████████| 726563/726563 [00:01<00:00, 433511.35it/s]
100%|██████████| 738282/738282 [00:01<00:00, 665718.40it/s]
100%|██████████| 744141/744141 [00:00<00:00, 831024.08it/s]
100%|██████████| 747071/747071 [00:01<00:00, 540167.84it/s]
100%|██████████| 748536/748536 [00:01<00:00, 510596.35it/s]
100%|██████████| 749268/749268 [00:01<00:00, 645367.78it/s]
100%|██████████| 749634/749634 [00:01<00:00, 512395.64it/s]
100%|██████████| 749817/749817 [00:01<00:00, 497211.23it/s]
100%|██████████| 749909/749909 [00:03<00:00, 240124.40it/s]
100%|██████████| 749955/749955 [00:03<00:00, 223610.62it/s]
100%|██████████| 749978/749978 [00:02<00:00, 277051.32it/s]
100%|██████████| 749989/749989 [00:01<00:00, 688031.45it/s]
100%|██████████| 749995/749995 [00:01<00:00, 635558.38it/s]
100%|██████████| 749998/749998 [00:00<00:00, 844591.88it/s]
100%|██████████| 749999/749999 [00:00<00:00, 1111006.50it/s]----------------
compare_count=48202583, move_count=104107719
result5_des: [1999, 2001, 2006, 2006, 2009]

冒泡排序

def bubble_sort(numberlist):
    compare_count = 0
    move_count = 0
    length = len(numberlist)
    for i in tqdm(range(length)):
        for j in range(1, length - i):
            compare_count += 1
            if numberlist[j - 1] > numberlist[j]:
                move_count += 3
                numberlist[j], numberlist[j - 1] = numberlist[j - 1], numberlist[j]
    print("----------------\ncompare_count=%d, move_count=%d"%(compare_count, move_count))
    return numberlist

# eazy_test = [5,3,4,1,2]
# result_bubble = bubble_sort(eazy_test)
# result_bubble

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = bubble_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = bubble_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = bubble_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = bubble_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = bubble_sort(test_750000)
print("result5_des:",result5[1000:1005])
----------------
compare_count=10, move_count=24





[1, 2, 3, 4, 5]

快速排序

对一组无序的数据集合,选择任意元素作为基准点

  • 该基准点左边的所有记录都小于或等于它。
  • 是基准点右边的所有记录都大于多等于它。
  • 然后重复上述操作,分别对左右半区进行快速排序。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UMMpfmYl-1623653033852)(./img/quick_sort.png)]

是不稳定的排序。

需要一个栈空间来实现递归。

quick_compare_count = 0
quick_move_count = 0
def quick_sort(arr):
        global quick_move_count
        global quick_compare_count
        if len(arr) < 2:
            return arr
        else:
            pivot = arr[0]
            less = [i for i in arr[1:] if i <= pivot]
            quick_compare_count += len(less)
            greater = [i for i in arr[1:] if i > pivot]
            quick_compare_count += len(greater)
            return quick_sort(less) + [pivot] + quick_sort(greater)

def use_quick_sort(arr):  # 封装一下排序和输出性能指标
    global quick_move_count
    global quick_compare_count
    result = quick_sort(arr)
    quick_move_count = len(arr)*3  # 非原地操作
    print("----------------\nquick_compare_count=%d, quick_move_count=%d"%(quick_compare_count, quick_move_count))
    quick_compare_count = 0  # 重置全局变量
    quick_move_count = 0
    return result

# eazy_test = [5,4,3,1,2]
# result_quick = use_quick_sort(eazy_test)
# result_quick

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = use_quick_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = use_quick_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = use_quick_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = use_quick_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = use_quick_sort(test_750000)
print("result5_des:",result5[1000:1005])
----------------
quick_compare_count=980853, quick_move_count=150000
result1_des: [2004, 2004, 2006, 2007, 2011]
----------------
quick_compare_count=2085025, quick_move_count=300000
result2_des: [1995, 1995, 1999, 1999, 2002]
----------------
quick_compare_count=5326159, quick_move_count=750000
result3_des: [1981, 1982, 1983, 1985, 1987]
----------------
quick_compare_count=11176179, quick_move_count=1500000
result4_des: [2000, 2001, 2006, 2007, 2013]
----------------
quick_compare_count=17951320, quick_move_count=2250000
result5_des: [1999, 2001, 2006, 2006, 2009]

简单选择排序

  • 通过n-1次关键字比较,从n个记录中找出关键字最小的记录,将它与第一个记录交换。
  • 通过n-2次比较,从剩余的n-1个记录中找出关键字次小的记录。
  • 重复上述操作,进行n-1躺排序后结束。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-95a11BSM-1623653033856)(./img/select_sort.png)]

select_compare_count = 0
select_move_count = 0
def findSmallest(arr):  # 用于查找出数组中最小的元素,返回最小元素的索引。
    global select_compare_count
    smallest = arr[0]
    smallest_index = 0
    for i in range(1, len(arr)):
        select_compare_count += 1
        if smallest > arr[i]:
            smallest = arr[i]
            smallest_index = i
    return smallest_index

def selectSort(arr):
    global select_move_count
    global select_compare_count
    newArr = []
    while arr:
        smallest = findSmallest(arr)
        newArr.append(arr.pop(smallest))
        select_move_count += 3  # 添加一个就是移动一次

    print("----------------\nselect_compare_count=%d, select_move_count=%d"%(select_compare_count, select_move_count))
    select_move_count = 0
    select_compare_count = 0
    return newArr

# eazy_test = [5,3,4,1,2]
# result_select = selectSort(eazy_test)
# result_select

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = selectSort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = selectSort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = selectSort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = selectSort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = selectSort(test_750000)
print("result5_des:",result5[1000:1005])
----------------
select_compare_count=10, select_move_count=15





[1, 2, 3, 4, 5]

堆排序

大根堆:根结点(即堆顶)的关键字是堆里所有结点关键字中最大者的堆,称为大根堆。

小根堆:根结点(即堆顶)的关键字是堆里所有结点关键字中最小者的堆,称为小根堆。

堆排序的思路:

  • 按某种方法生成大根堆,该大根堆的根就是键值最大的元素。
  • 将根与向量尾部的元素进行互换,即最大值放到向量的末尾(有序区)。
  • 将剩余的n-1个元素再次调整成大根堆,可得到次大值。
  • 将次大值放到向量的倒数第二的位置。
  • ······
  • 如此反复,直到全部关键字排好序为止。
heap_compare_count = 0
heap_move_count = 0

def heap_sort(numberlist):
    global heap_compare_count
    global heap_move_count
    length = len(numberlist)
    def sift_down(start, end):
        global heap_compare_count
        global heap_move_count  
        root = start
        while True:
            child = 2 * root + 1
            heap_compare_count += 1
            if child > end:
                break
            if child + 1 <= end and numberlist[child] < numberlist[child + 1]:
                child += 1
            if numberlist[root] < numberlist[child]:
                numberlist[root], numberlist[child] = numberlist[child], numberlist[root]
                root = child
            else:
                break

# 创建最大堆
    for start in range((length - 2) // 2, -1, -1):
        sift_down(start, length - 1)

# 堆排序
    for end in range(length - 1, 0, -1):
        numberlist[0], numberlist[end] = numberlist[end], numberlist[0]
        heap_move_count += 3  # 上面这步交换了元素
        sift_down(0, end - 1)

    print("----------------\nheap_compare_count=%d, heap_move_count=%d"%(heap_compare_count, heap_move_count))
    return numberlist

# eazy_test = [5,3,4,1,2]
# result_heap = heap_sort(eazy_test)
# result_heap

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = heap_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = heap_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = heap_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = heap_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = heap_sort(test_750000)
print("result5_des:",result5[1000:1005])
----------------
heap_compare_count=762668, heap_move_count=149997
result1_des: [2004, 2004, 2006, 2007, 2011]
----------------
heap_compare_count=2387129, heap_move_count=449994
result2_des: [1995, 1995, 1999, 1999, 2002]
----------------
heap_compare_count=6774243, heap_move_count=1199991
result3_des: [1981, 1982, 1983, 1985, 1987]
----------------
heap_compare_count=16049310, heap_move_count=2699988
result4_des: [2000, 2001, 2006, 2007, 2013]
----------------
heap_compare_count=30417757, heap_move_count=4949985
result5_des: [1999, 2001, 2006, 2006, 2009]

归并排序

将若干已排好序的子序列合并成一个有序的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R5y6Sa14-1623653033859)(./img/merge_sort.png)]

merge_compare_count = 0
merge_move_count = 0

def merge(left, right):
    global merge_compare_count
    global merge_move_count
    result = []
    while left and right:
        merge_compare_count += 1
        if left[0] < right[0]:
            result.append(left.pop(0))
            merge_move_count += 3
        else:
            result.append(right.pop(0))
            merge_move_count += 3
    if left:
        result += left
        merge_move_count += 3*len(left)
    if right:
        result += right
        merge_move_count += 3*len(right)
    return result

def merge_sort(numberlist):
    global merge_compare_count
    global merge_move_count
    if len(numberlist) <= 1:
        return numberlist
    mid = len(numberlist) // 2
    left = numberlist[:mid]
    right = numberlist[mid:]

    left = merge_sort(left)
    right = merge_sort(right)
    return merge(left, right)

def use_merge_sort(numberlist):
    global merge_compare_count
    global merge_move_count
    result = merge_sort(numberlist)
    print("----------------\nmerge_compare_count=%d, merge_move_count=%d"%(merge_compare_count, merge_move_count))
    merge_compare_count = 0
    merge_move_count = 0
    return result

# eazy_test = [5,3,4,1,2]
# reslut_merge = use_merge_sort(eazy_test)
# reslut_merge

# 从文件中读取数据
test_50000 = pd.read_csv("./test_50000.csv")['0'].tolist()
test_100000 = pd.read_csv("./test_100000.csv")['0'].tolist()
test_250000 = pd.read_csv("./test_250000.csv")['0'].tolist()
test_500000 = pd.read_csv("./test_500000.csv")['0'].tolist()
test_750000 = pd.read_csv("./test_750000.csv")['0'].tolist()

# 排序并打印结果
result1 = use_merge_sort(test_50000)
print("result1_des:",result1[1000:1005])

result2 = use_merge_sort(test_100000)
print("result2_des:",result2[1000:1005])

result3 = use_merge_sort(test_250000)
print("result3_des:",result3[1000:1005])

result4 = use_merge_sort(test_500000)
print("result4_des:",result4[1000:1005])

result5 = use_merge_sort(test_750000)
print("result5_des:",result5[1000:1005])
----------------
merge_compare_count=718195, merge_move_count=2353392
result1_des: [2004, 2004, 2006, 2007, 2011]
----------------
merge_compare_count=1536506, merge_move_count=5006784
result2_des: [1995, 1995, 1999, 1999, 2002]
----------------
merge_compare_count=4168546, merge_move_count=13463568
result3_des: [1981, 1982, 1983, 1985, 1987]
----------------
merge_compare_count=8836763, merge_move_count=28427136
result4_des: [2000, 2001, 2006, 2007, 2013]
----------------
merge_compare_count=13706065, merge_move_count=44104272
result5_des: [1999, 2001, 2006, 2006, 2009]

时间有点赶,这是一次实验作业,比较次数方面可能会有错误,欢迎指正,排序方面是实现了的,希望对你有所帮助。
github(jupyter源码):https://github.com/Justin3go/Algorithm-and-data-structure

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值