Python 使用修改的快速排序查找元素的秩
我试图找到一个元素的秩,定义为k,在一个未排序的列表中,秩是列表中第k个最低的值 例如。 给出一个列表: [5,4,1,10,8,3,2] 其中k为1,值为1 其中k为3,值为3 其中k为6,值为8 其中k为7,值为10 我必须使用下面提供的修改过的快速排序分区函数Python 使用修改的快速排序查找元素的秩,python,algorithm,Python,Algorithm,我试图找到一个元素的秩,定义为k,在一个未排序的列表中,秩是列表中第k个最低的值 例如。 给出一个列表: [5,4,1,10,8,3,2] 其中k为1,值为1 其中k为3,值为3 其中k为6,值为8 其中k为7,值为10 我必须使用下面提供的修改过的快速排序分区函数 def partition(a_list, first, last): pivot = a_list[last] i = first - 1 for j in range(first, last):
def partition(a_list, first, last):
pivot = a_list[last]
i = first - 1
for j in range(first, last):
if a_list[j] <= pivot:
i += 1
a_list[i], a_list[j] = a_list[j], a_list[i]
a_list[i + 1], a_list[last] = a_list[last], a_list[i + 1]
return i + 1
那么,是的,我如何在预期的运行时间O(n)递归地查找给定某个等级的元素,而不必对整个列表进行排序呢?而仅限于这种特殊的分区方式。Python食谱中至少有两个已解决的示例和示例 这是我的版本:
import random
def select(data, n):
"Find the nth rank ordered element (the least value has rank 0)."
data = list(data)
if not 0 <= n < len(data):
raise ValueError('not enough elements for the given rank')
while True:
pivot = random.choice(data)
pcount = 0
under, over = [], []
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
if n < len(under):
data = under
elif n < len(under) + pcount:
return pivot
else:
data = over
n -= len(under) + pcount
随机导入
def选择(数据,n):
“查找第n个秩有序元素(最小值的秩为0)。”
数据=列表(数据)
如果不是0轴:
奥佩德(埃伦)
其他:
pcount+=1
如果n
根据您的要求,下面是相同代码的递归版本:
def select(data, n):
"Find the nth rank ordered element (the least value has rank 0)."
if not 0 <= n < len(data):
raise ValueError('not enough elements for the given rank')
pivot = random.choice(data)
pcount = 0
under, over = [], []
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
if n < len(under):
return select(under, n)
elif n < len(under) + pcount:
return pivot
else:
return select(over, n - len(under) - pcount)
def选择(数据,n):
“查找第n个秩有序元素(最小值的秩为0)。”
如果不是0轴:
奥佩德(埃伦)
其他:
pcount+=1
如果n
试试这个?一个可能有用的观察结果是分区函数返回pivot元素的索引(从零开始)
def selection(a_list, first, last, k):
assert (k - 1 >= first)
assert (k - 1 <= last)
intReturn = partition(a_list, first, last)
if intReturn + 1 == k:
return a_list[intReturn]
if intReturn + 1 < k:
return selection(a_list, intReturn + 1, last, k)
if intReturn + 1 > k:
return selection(a_list, first, intReturn - 1, k)
def选择(一个列表,第一个,最后一个,k):
断言(k-1>=第一个)
断言(k-1k:
返回选择(a_列表,第一,intReturn-1,k)
这是一个很好的解决方案,避免了数组都是同一元素时的二次运行时间!谢谢!虽然最初的另一个答案看起来更详细,但实际上并没有返回所提供的预期答案。我现在可以清楚地看到我在尝试拆分为两半时所犯的逻辑错误,因此这更有意义现在!
def select(data, n):
"Find the nth rank ordered element (the least value has rank 0)."
if not 0 <= n < len(data):
raise ValueError('not enough elements for the given rank')
pivot = random.choice(data)
pcount = 0
under, over = [], []
uappend, oappend = under.append, over.append
for elem in data:
if elem < pivot:
uappend(elem)
elif elem > pivot:
oappend(elem)
else:
pcount += 1
if n < len(under):
return select(under, n)
elif n < len(under) + pcount:
return pivot
else:
return select(over, n - len(under) - pcount)
def selection(a_list, first, last, k):
assert (k - 1 >= first)
assert (k - 1 <= last)
intReturn = partition(a_list, first, last)
if intReturn + 1 == k:
return a_list[intReturn]
if intReturn + 1 < k:
return selection(a_list, intReturn + 1, last, k)
if intReturn + 1 > k:
return selection(a_list, first, intReturn - 1, k)