我发布了一个关于三个问题的快速排序中位数的帮助。我需要实现一个分区,该分区使用一个支点,该支点是输入列表中三个元素(开始、中间、结束)的中位数,同时考虑一些边的情况。
简而言之,我需要实现一个方法choose_median(),它返回中位数元素的索引(所选枢轴);打印上一步选择的枢轴的索引;创建一个分区()方法,以便它可以与所选枢轴一起工作;在第一个分区之后打印列表。
我在这个案子上遇到了麻烦:
“注意,如果列表的大小是偶数,有两种方法可以选择中位数元素。为了避免歧义,在这种情况下选择索引较小的元素作为中位数。”
这看起来很难,我已经难倒了一段时间。尤其是在长度为2或更小的列表上。
如果给定适当的支点,我有一个适用于情况的分区方法:
def partition(arr, pivot):
less, equal, greater = [], [], []
for val in arr:
if val < pivot: less.append(val)
if val == pivot: equal.append(val)
if val > pivot: greater.append(val)
return less+equal+greater, pivot
我也可以更改此功能以使用枢轴。
def partition(lst, pivot, start, end):
j = start
for i in range(start + 1, end + 1):
if lst[i] <= lst[start]:
j += 1
lst[i], lst[j] = lst[j], lst[i]
lst[start], lst[j] = lst[j], lst[start]
return j
用奇数列表选择中位数很简单。
此外,我已经看到/知道如何在这里实现实现:
Python:中位数为3的快速排序
任何帮助将不胜感激。
你似乎让这变得比实际更难。首先,我认为你混淆了“中值”和“中间元素”的术语。
列表的中间元素,向下舍入,只是lst[(len(lst)-1)//2]
:您的索引是列表长度,减1,整数除以2。
因此,您的透视选择很容易:获取三个指示的元素,对它们进行排序,然后返回中间的元素。
def choose_pivot(lst):
return sorted( [lst[0],
lst[-1],
lst[(len(lst)-1) //2]
])[1]