程序未正确选择选择排序算法中列表中的最小值

时间:2018-12-09 01:28:20

标签: python python-3.x algorithm selection-sort

我正在用Python编写一个程序,该程序实现选择排序算法并以降序对列表的元素进行排序。

假设我的输入是l = [242, 18, 44, 201, 1111]

我的逻辑如下:

  • l = [242, 18, 44, 201, 1111] # switch l[0] (242) and l[len(l)-1] (1111)
  • l = [1111, 18, 44, 201, 242] # switch l[1] (18) and l[len(l)-1] (242)
  • l = [1111, 242, 44, 201, 18] # switch l[2] (44) and l[len(l)-2] (201)

输出为[1111, 242, 201, 44, 18]

因此,这是我根据上述逻辑实现的代码:

def selSort(l):
    '''Sorts the list in descending order using a selection sort algorithm.

    Params: l (list): unsorted list
    Sorts: unsorted list in descending order
    '''
    start = len(l)-1
    while start != 0:
        for i in range(len(l)):
            if l[i] < l[start]:
                l[i], l[start] = l[start], l[i]
        start -= 1

似乎我高估了我的逻辑,因为算法的输出为[1111, 18, 242, 201, 44]

经过一些调试之后,我发现在对遍历l进行了几次遍历之后,while循环仍然没有达到终止条件。这意味着starti之间会有一些不必要的重叠。例如,当start = 3i = 4时,l[i] < l[start]产生l = [1111, 242, 201, 18, 44]。再次遍历之后,我们将得到上面显示的错误输出。

对于此问题,什么是优雅的解决方案(我知道选择排序不是最有效的算法)和Pythonic解决方案?我正在尝试不使用任何内置函数(lenrange除外),方法或外部库(如果可能)来实现此目的。

我已经在此处签出了Selection Sort Algorithm PythonSelection Sort Algorithm in Java帖子。前者使用列表方法(我试图避免这种方法),而我对Java语法的理解不够充分,无法利用后者。

2 个答案:

答案 0 :(得分:2)

这应该有效。它还使用range()来避免必须使用while循环。

from collections import Counter
import numpy as np
from scipy import linalg


lhs = (Counter({22.99: 1}), Counter({12.011: 2, 15.999: 2}), Counter({12.011: 7}))
rhs = Counter({12.011: 15, 15.999: 1})

# get unique keys that occur in any Counter in 2D
# each unique key represents a separate dimension
ks = np.array([*set().union(rhs, *lhs)])[:, None]

# get a helper function to convert Counters to vectors
ctr_to_vec = np.vectorize(Counter.__getitem__)

lhs_mat = ctr_to_vec(lhs, ks)
rhs_vec = ctr_to_vec(rhs, ks)

# compute coefficients solving the least-squares problem
coefs = linalg.lstsq(lhs_mat, rhs_vec)[0]

is_linear_comb = np.allclose(lhs_mat @ coefs, rhs_vec)

答案 1 :(得分:2)

选择排序算法(降序)的逻辑是:对表进行n-1次迭代(n是列表中元素的数量)。在第i次迭代中,我们选择索引i + 1和n之间的最高元素,然后将该元素与列表中位置i的元素交换。这将导致以下代码:

def selSort(l):
    '''Sorts the list in descending order using a selection sort algorithm.

    Params: l (list): unsorted list
    Sorts: unsorted list in descending order
    '''
    for i in range(len(l)-1) :
        posMax = i
        for j in range(i+1,len(l)):
            if l[j] > l[posMax]:
                posMax = j
        l[posMax], l[i] = l[i], l[posMax]
    return l

l = selSort([242, 18, 44, 201, 1111])
print(l) #prints [1111, 242, 201, 44, 18]