我有一个整数列表,我想使用选择来查找这个未排序列表的中位数。这是我到目前为止所做的,但我没有为我的测试列表[140, 240, 180, 400, 340]
获得任何输出。有人能解释为获得中位数需要做些什么吗?
我的代码
def fastSelect(aList, k):
count = 0
pivot = 0
smallerList = []
largeList = []
while aList != []:
pivot == len(aList)//2
for i in range(0,pivot):
smallerList.append(aList[i])
for j in range(pivot + 1,len(aList)):
largeList.append(aList[j])
for g in range(0,len(aList)):
if aList[g] == pivot:
count += 1
m = len(smallerList)
if k >= m and k < m + count:
return pivot
if m > k:
aList = smallerList
else:
k = k - m - count
aList = largeList
答案 0 :(得分:0)
您实际上并未与pivot
值进行比较。您还有一个错误,即您使用==
代替=
进行pivot
初始化的分配。
def fastSelect(aList, k):
while aList:
smallerList = []
largeList = []
count = 0
pivot = aList[len(aList) // 2]
for i in aList:
if i < pivot:
smallerList.append(i)
elif i > pivot:
largeList.append(i)
else:
count += 1
m = len(smallerList)
if k >= m and k < m + count:
return pivot
if m > k:
aList = smallerList
else:
k = k - m - count
aList = largeList
要理解为什么pivot
成为中位数,你需要考虑中位数的定义是什么。中位数是列表中的值,小于或等于其他值的一半,大于或等于其他值的一半。
第一次循环时,中间值被选为pivot
。然后,它将列表拆分为两个列表:一个包含小于pivot
的值,另一个包含大于pivot
的值。类似地,保持等于count
的{{1}}个值。接下来,它会看到每个列表中有多少个值。如果两个列表的大小相同或相差pivot
,那么根据定义,我们找到了中位数,因此我们返回count
。
所以现在我们必须在整个循环中保持这个不变量。让我们看看每个案例。如果pivot
(表示为smallerList
)的大小大于m
,那么中位数必须在k
内,我们仍然在寻找{{} {}}内部的1}}元素。如果smallerList
大于kth
,则中位数必须在smallerList
内,但我们不再需要k
内的m
元素,因为我们已经找到largeList
和kth
元素小于或等于largeList
,因此我们会在继续循环之前从m
中减去这些元素。
最后,您实际上可以通过使用随机数据透视来改进此代码。如果你看一下维基百科关于Quickselect algorithm的文章,你会看到一个随机的转轴可以保证几乎一定的线性时间复杂度,而你所选择的中间位置转轴具有更可预测的最坏情况分析。