提问者:小点点

快速排序-具有边缘情况的三个中位数


我发布了一个关于三个问题的快速排序中位数的帮助。我需要实现一个分区,该分区使用一个支点,该支点是输入列表中三个元素(开始、中间、结束)的中位数,同时考虑一些边的情况。

简而言之,我需要实现一个方法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的快速排序

任何帮助将不胜感激。


共1个答案

匿名用户

你似乎让这变得比实际更难。首先,我认为你混淆了“中值”和“中间元素”的术语。

列表的中间元素,向下舍入,只是lst[(len(lst)-1)//2]:您的索引是列表长度,减1,整数除以2。

因此,您的透视选择很容易:获取三个指示的元素,对它们进行排序,然后返回中间的元素。

def choose_pivot(lst):
    return sorted( [lst[0],
                    lst[-1],
                    lst[(len(lst)-1) //2]
                   ])[1]