鱼C论坛

 找回密码
 立即注册
查看: 3310|回复: 41

[技术交流] 插入法排序和合并法排序

[复制链接]
发表于 2023-5-16 08:13:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 yinda_peng 于 2023-5-31 08:07 编辑

看到陶远航的帖子,突然想起来自己这学期大作业就是做的这个主题,因为这学期主要是numpy和pandas,所以用了这两个模块,考虑矩阵。


程序部分的设计主要是对插入法排序和合并法排序进行了时间上的对比:
  1. import pandas as pd
  2. import numpy as np
  3. import time
  4. def insertion_sort(arr):
  5.     for i in range(1, len(arr)):
  6.         key = arr
  7.         j = i - 1
  8.         while j >= 0 and key < arr[j]:
  9.             arr[j + 1] = arr[j]
  10.             j -= 1
  11.         arr[j + 1] = key
  12. def merge(arr, left, middle, right):
  13.     n1 = middle - left + 1
  14.     n2 = right - middle
  15.     L = [arr[left + i] for i in range(n1)]
  16.     R = [arr[middle + 1 + i] for i in range(n2)]
  17.     i = j = 0
  18.     k = left
  19.     while i < n1 and j < n2:
  20.         if L <= R[j]:
  21.             arr[k] = L
  22.             i += 1
  23.         else:
  24.             arr[k] = R[j]
  25.             j += 1
  26.         k += 1
  27.     while i < n1:
  28.         arr[k] = L
  29.         i += 1
  30.         k += 1
  31.     while j < n2:
  32.         arr[k] = R[j]
  33.         j += 1
  34.         k += 1
  35. def merge_sort(arr, left, right):
  36.     if left < right:
  37.         middle = (left + right) // 2
  38.         merge_sort(arr, left, middle)
  39.         merge_sort(arr, middle+1, right)
  40.         merge(arr, left, middle, right)
  41. class SortTest:
  42.     def __init__(self, size):
  43.         self.arr = np.random.randint(size, size=size)
  44.         self.insertion_time = None
  45.         self.merge_time = None
  46.     def test_insertion(self):
  47.         arr_copy = self.arr.copy()
  48.         start = time.time()
  49.         insertion_sort(arr_copy)
  50.         self.insertion_time = time.time() - start
  51.     def test_merge(self):
  52.         arr_copy = self.arr.copy()
  53.         start = time.time()
  54.         merge_sort(arr_copy, 0, len(arr_copy) - 1)
  55.         self.merge_time = time.time() - start
  56. if __name__ == '__main__':
  57.     size = 10000
  58.     sort_test = SortTest(size)
  59.     sort_test.test_insertion()
  60.     sort_test.test_merge()
  61.     df_data = {"size": [size], "insertion time": [sort_test.insertion_time], "merge time": [sort_test.merge_time]}
  62.     df_results = pd.DataFrame(data=df_data)
  63.     print(df_results)
复制代码

[i][i]输出结果:[/i][/i]
[i][i]    size  insertion time  merge time[/i][/i]
[i][i]0  10000        4.334727    0.042265[/i][/i]
[i][i]在这个代码中,我们定义了插入法排序和合并法排序两个函数,分别用于对数组进行排序。同时,我们也实现了一个名为SortTest的类,用于生成随机数数组并测试两种排序算法的执行时间。最终,我们通过Pandas的DataFrame输出了排序结果。需要注意的是,由于Python的内置排序函数sorted()已经使用了优化后的快速排序(Quicksort),因此在实际应用中,如果只是为了排序而不需要手写算法,可以考虑直接使用sorted()函数进行排序,以免重复造轮子。[/i][/i]
[i][i]可能会觉得既然已经有sorted()函数了,我们做这个有什么意义,但是对排序进行一定层级的理解是非常有必要的,我们使用其他的编程语言就不一定有像python这样的sorted()函数了,是以这对我们以后学习编程是十分有帮助的。[/i][/i]
[i][i]同时可以利用合并排序法对矩阵的某一行或者某一列进行排序:[/i][/i]
  1. import pandas as pd
  2. import numpy as np
  3. def merge(arr, left, middle, right):
  4.     n1 = middle - left + 1
  5.     n2 = right - middle
  6.     L = [arr[left + i] for i in range(n1)]
  7.     R = [arr[middle + 1 + i] for i in range(n2)]
  8.     i = j = 0
  9.     k = left
  10.     while i < n1 and j < n2:
  11.         if L <= R[j]:
  12.             arr[k] = L
  13.             i += 1
  14.         else:
  15.             arr[k] = R[j]
  16.             j += 1
  17.         k += 1
  18.     while i < n1:
  19.         arr[k] = L
  20.         i += 1
  21.         k += 1
  22.     while j < n2:
  23.         arr[k] = R[j]
  24.         j += 1
  25.         k += 1
  26. def merge_sort_row(matrix, row):
  27.     merge_sort(matrix[row], 0, len(matrix[row]) - 1)
  28. if __name__ == '__main__':
  29.     matrix = np.random.randint(100, size=(5, 5))
  30.     print(f"Before sorting:\n{matrix}")
  31.     row_to_sort = 3
  32.     merge_sort_row(matrix, row_to_sort)
  33.     print(f"After sorting row {row_to_sort}:\n{matrix}")
复制代码

[i][i]输出结果:[/i][/i]
[i][i]Before sorting:[/i][/i]
[i][i][[82  0 67  5 36][/i][/i]
[i][i] [42 38 13 21 45][/i][/i]
[i][i] [33 41 87 67 81][/i][/i]
[i][i] [10 70 57 25 40][/i][/i]
[i][i] [88 18 90 96 65]][/i][/i]
[i][i]After sorting row 3:[/i][/i]
[i][i][[82  0 67  5 36][/i][/i]
[i][i] [42 38 13 21 45][/i][/i]
[i][i] [33 41 87 67 81][/i][/i]
[i][i] [10 25 40 57 70][/i][/i]
[i][i] [88 18 90 96 65]][/i][/i]
[i][i]代码首先生成了一个随机矩阵,然后选择了需要排序的行号(在本例中为第三行)。最终使用merge_sort_row()函数进行排序。该函数中,我们直接使用了前面代码的merge_sort()函数,但是因为矩阵的行是一个一维数组,所以直接传入了matrix[row]作为排序对象。同理,如果需要对某一列进行合并法排序,只需将合并排序算法中对于下标的操作改为操作矩阵的列即可,或者应用矩阵转置来实现。提一句,在Numpy库中也有和sorted对应的用于矩阵某行某列排序的函数numpy.sort,还有实现间接排序的函数argsort和lexsort,不过多延伸了。[/i][/i]
[i][i]今天下午C语言考试,祝我好运(满绩)[/i][/i]

评分

参与人数 6荣誉 +3 鱼币 +3 贡献 0 收起 理由
梦想护卫舰官方 + 1 + 1 鱼C有你更精彩^_^
myd0313 + 1 + 1 无条件支持楼主!
myd0311 + 1 + 1 无条件支持楼主!
sfqxx + 3
不二猫猫 -5 -5 -3 感谢楼主无私奉献!
zhangjinxuan + 5 + 5 好帖,学到了!

查看全部评分

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2023-5-16 08:21:18 | 显示全部楼层
@夏季的春秋 mouse man
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 18:01:03 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2023-5-16 18:01:41 | 显示全部楼层

回帖奖励 +2 鱼币

鱼币飞来@sfqxx_小
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 18:02:14 | 显示全部楼层
sfqxx 发表于 2023-5-16 18:01
首楼
@zhangjinxuan @歌者文明清理员 @星期五打篮球 @中英文泡椒 @一点沙

支持!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 18:02:48 | 显示全部楼层

再来一次

建议使用表情+文字
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 18:03:05 | 显示全部楼层

回帖奖励 +2 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-16 18:05:23 | 显示全部楼层
sfqxx 发表于 2023-5-16 18:01
首楼
@zhangjinxuan @歌者文明清理员 @星期五打篮球 @中英文泡椒 @一点沙

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 18:06:09 | 显示全部楼层

回帖奖励 +2 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 19:17:46 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-16 19:18:11 | 显示全部楼层

回帖奖励 +2 鱼币

支持支持
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 19:18:42 | 显示全部楼层

回帖奖励 +2 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-5-16 20:07:05 | 显示全部楼层
考完了,满绩不可能了,考得真的细,错了好几题了已经
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 20:23:22 | 显示全部楼层

支持支持
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-16 22:14:06 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-17 10:11:26 | 显示全部楼层

回帖奖励 +2 鱼币

sfqxx 发表于 2023-5-16 18:02
再来一次

建议使用表情+文字

支持!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-17 10:26:38 | 显示全部楼层
考试冲冲冲!!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-17 13:02:13 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-17 13:04:43 | 显示全部楼层

回帖奖励 +2 鱼币

渔币
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-18 09:57:31 | 显示全部楼层

回帖奖励 +2 鱼币

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-24 00:05

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表