Python归并排序+插入排序混合添排序
Python merge sort + insertion sort hybrid Tim sort
我已经编写了插入排序和归并排序的代码。现在我想实现我的插入排序和合并排序到 Tim 排序。
我可以看到 Tim 排序的示例使用了开始、中间和结束输入,但是没有 no 应该可以做到这一点吗?
我想尽可能保持我的合并和插入排序,因为输入输出非常适合我的代码的其余部分。
from random import randint
minrun = 32
def insertion_sort(in_data):
s_data = list(in_data)
for i in range(1, len(s_data)):
key = s_data[i]
j = i - 1
while j >= 0 and key < s_data[j]:
s_data[j + 1] = s_data[j]
j -= 1
s_data[j + 1] = key
return s_data
def merge(a, b):
c = []
a_idx, b_idx = 0, 0
while a_idx < len(a) and b_idx < len(b):
if a[a_idx] < b[b_idx]:
c.append(a[a_idx])
a_idx += 1
else:
c.append(b[b_idx])
b_idx += 1
if a_idx == len(a):
c.extend(b[b_idx:])
else:
c.extend(a[a_idx:])
return c
def merge_sort(a):
if len(a) <= 1:
return a
left, right = merge_sort(a[:len(a) // 2]), merge_sort(a[len(a) // 2:])
return merge(left, right)
def tim_sort(in_data):
n = len(in_data)
for start in range(0, n, minrun):
end = min(start + minrun - 1, n - 1)
in_data = insertion_sort(in_data, start, end)
curr_size = minrun
while curr_size < n:
for start in range(0, n, curr_size * 2):
mid = min(n - 1, start + curr_size - 1)
end = min(n - 1, mid + curr_size)
in_data = merge_sort(in_data, start, mid, end)
curr_size *= 2
return in_data
def create_array(size=10, max=50):
from random import randint
return [randint(0, max) for _ in range(size)]
我找到了这个 Tim 排序的例子,但我很困惑如何让它在我的代码中工作。
2020 年 11 月 27 日
不清楚您从何处获得此示例,但肯定不是 timsort。如果你想实现timsort,首先要做的是阅读并理解 Tim Peters对算法的描述:
https://svn.python.org/projects/python/trunk/Objects/listsort.txt
这是关于 timsort 的权威文档。你可以用google找到各种垃圾。我发现的唯一可能值得一读以弄湿你的脚的参考资料是:
https://www.infopulse.com/blog/timsort-sorting-algorithm
这是轻量级的,但相当完整并且在任何方面都没有严重错误。但是,它确实忽略了对奔腾的任何考虑,这是算法中最棘手的部分。
意识到 python
是一种动态语言很重要,因此笨拙地实现 timsort 会产生一些东西,由于内部对象分配而使用大量过量的内存。 Timsort 要求:
- 排序就地
- 稳定性
- 保持不变
- 奔腾
- 彻底测试
在 python
中就地排序意味着手动索引数据列表。如果使用切片,则每次都会分配和释放内存。
据我所知,网络上有三种 python
值得参考的实施方式以供参考:
1 https://github.com/reingart/pypy/blob/master/rpython/rlib/listsort.py
2 https://gist.github.com/ruminations/89a045dc0ef7edfb92304a0de0752ee0
3 https://github.com/hu-ng/timsort
第一个是 pypy
主干的一部分,在 rpython
中实现。它似乎是对 cpython
实现的改编。 rpython
是 python 的一个受限子集,用于静态编译。
第二个是经过充分测试的实现,有详细的文档记录且可读性很强。最后一个显然是大学练习,看起来是完整和正确的,但没有经过很好的测试。
您可以在 python 实现 timsort 时找到许多其他尝试,但我所看到的要么无法满足基本要求,要么明显不正确。
最后,如果您希望有人帮助您调整您的代码,您至少应该 link,但最好直接提供,因为 mergesort 和 insort 都不难编写代码。
我已经编写了插入排序和归并排序的代码。现在我想实现我的插入排序和合并排序到 Tim 排序。
我可以看到 Tim 排序的示例使用了开始、中间和结束输入,但是没有 no 应该可以做到这一点吗?
我想尽可能保持我的合并和插入排序,因为输入输出非常适合我的代码的其余部分。
from random import randint
minrun = 32
def insertion_sort(in_data):
s_data = list(in_data)
for i in range(1, len(s_data)):
key = s_data[i]
j = i - 1
while j >= 0 and key < s_data[j]:
s_data[j + 1] = s_data[j]
j -= 1
s_data[j + 1] = key
return s_data
def merge(a, b):
c = []
a_idx, b_idx = 0, 0
while a_idx < len(a) and b_idx < len(b):
if a[a_idx] < b[b_idx]:
c.append(a[a_idx])
a_idx += 1
else:
c.append(b[b_idx])
b_idx += 1
if a_idx == len(a):
c.extend(b[b_idx:])
else:
c.extend(a[a_idx:])
return c
def merge_sort(a):
if len(a) <= 1:
return a
left, right = merge_sort(a[:len(a) // 2]), merge_sort(a[len(a) // 2:])
return merge(left, right)
def tim_sort(in_data):
n = len(in_data)
for start in range(0, n, minrun):
end = min(start + minrun - 1, n - 1)
in_data = insertion_sort(in_data, start, end)
curr_size = minrun
while curr_size < n:
for start in range(0, n, curr_size * 2):
mid = min(n - 1, start + curr_size - 1)
end = min(n - 1, mid + curr_size)
in_data = merge_sort(in_data, start, mid, end)
curr_size *= 2
return in_data
def create_array(size=10, max=50):
from random import randint
return [randint(0, max) for _ in range(size)]
我找到了这个 Tim 排序的例子,但我很困惑如何让它在我的代码中工作。
2020 年 11 月 27 日
不清楚您从何处获得此示例,但肯定不是 timsort。如果你想实现timsort,首先要做的是阅读并理解 Tim Peters对算法的描述:
https://svn.python.org/projects/python/trunk/Objects/listsort.txt
这是关于 timsort 的权威文档。你可以用google找到各种垃圾。我发现的唯一可能值得一读以弄湿你的脚的参考资料是:
https://www.infopulse.com/blog/timsort-sorting-algorithm
这是轻量级的,但相当完整并且在任何方面都没有严重错误。但是,它确实忽略了对奔腾的任何考虑,这是算法中最棘手的部分。
意识到 python
是一种动态语言很重要,因此笨拙地实现 timsort 会产生一些东西,由于内部对象分配而使用大量过量的内存。 Timsort 要求:
- 排序就地
- 稳定性
- 保持不变
- 奔腾
- 彻底测试
在 python
中就地排序意味着手动索引数据列表。如果使用切片,则每次都会分配和释放内存。
据我所知,网络上有三种 python
值得参考的实施方式以供参考:
1 https://github.com/reingart/pypy/blob/master/rpython/rlib/listsort.py
2 https://gist.github.com/ruminations/89a045dc0ef7edfb92304a0de0752ee0
3 https://github.com/hu-ng/timsort
第一个是 pypy
主干的一部分,在 rpython
中实现。它似乎是对 cpython
实现的改编。 rpython
是 python 的一个受限子集,用于静态编译。
第二个是经过充分测试的实现,有详细的文档记录且可读性很强。最后一个显然是大学练习,看起来是完整和正确的,但没有经过很好的测试。
您可以在 python 实现 timsort 时找到许多其他尝试,但我所看到的要么无法满足基本要求,要么明显不正确。
最后,如果您希望有人帮助您调整您的代码,您至少应该 link,但最好直接提供,因为 mergesort 和 insort 都不难编写代码。