7

这似乎是一个简单的问题,但是当我尝试在 Python 中实现选择排序时,我没有得到排序列表。我的实现有问题吗?子集可能是个问题。

source = [4,2,1,10,5,3,100]
for i in range(len(source)):
  mini = min(source[i:]) #find minimum element
  min_index = source[i:].index(mini)-1 #find index of minimum element
  source[i:][min_index]= source[i:][0] #replace element at min_index with first element
  source[i:][0] = mini                  #replace first element with min element
print source
4

14 回答 14

14

我认为有几个问题。

首先,当您执行 source[i:] 时,我相信它会返回请求的子元素的新数组,而不是原始数组的一部分,因此如果您修改它,则不要修改原始数组。其次,你不应该从索引中减去 1。

source = [4,2,1,10,5,3,100]
for i in range(len(source)):
    mini = min(source[i:]) #find minimum element
    min_index = source[i:].index(mini) #find index of minimum element
    source[i + min_index] = source[i] #replace element at min_index with first element
    source[i] = mini                  #replace first element with min element
print source

这给出了:

[1, 2, 3, 4, 5, 10, 100]
于 2013-03-05T22:29:59.640 回答
4

这是我将如何重写您的代码。当然,在 Python 中我只是list.sort()用来对列表进行排序,但这里是 Python 中的选择排序。

我们创建了一个生成器表达式,(value, i)它从列表中返回一个值及其索引的元组。然后当min()求最小值时,它找到最低的元组值;由于值在索引之前的元组中首先出现,因此该值将是重要部分,并且min()会找到最低值。(如果有平局,min()将使用元组的第二部分,索引,作为平局破坏者。但对于排序,我们不关心平局是如何被打破的。)

现在,我们不再搜索子列表以找到最小值,然后再次搜索以找出索引,而是搜索一次并获得最小值和索引。

但我们实际上并不关心最小值;我们关心索引。所以min()完成后,我们只是丢弃实际值但保留索引。将索引调整为在整个列表中正确(而不是在列表的切片中),然后我们可以交换。

我们使用标准的 Python 习惯用法来交换两个值。Python 将构建一个元组对象作为中间对象,然后将该元组解包到左侧。

lst = [4,2,1,10,5,3,100]

for i_sortpos in range(len(lst)):
    # Make a generator expression to return (value, i) pairs.
    genexp = ((n, i) for i, n in enumerate(lst[i_sortpos:]))
    # Use genexp with min() to find lowest and its index.
    # (Use '_' for variable name for the actual value; we don't use it.)
    _, i_min = min(genexp)
    # Adjust index to be correct in full list.
    i_min += i_sortpos
    # Swap the number at i_sortpos with the lowest found.
    lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]

print(lst)

编辑:这是对上述内容的改进。列表中的切片实际上分配了一个新列表;我们这里的代码不需要一个新的列表,它只需要一个方便的方法来检查一个子列表。该itertools模块提供了一个函数 ,islice()该函数返回一个迭代器,该迭代器对列表的一部分进行迭代。这避免了在我们检查每个子列表时重复创建和销毁列表。

我相信这是在 Python 中进行选择排序的最有效方法。(你可以去掉我们将生成器表达式绑定到名称的部分genexp并节省几微秒......只需调用min()一个长的单行代码。但这不值得失去可读性。)

import itertools as it

lst = [4,2,1,10,5,3,100]

for i_sortpos in range(len(lst)):
    # Make a generator expression to return (value, i) pairs.
    # Use it.islice() for to look at sublist.
    genexp = ((n, i) for i, n in enumerate(it.islice(lst, i_sortpos, len(lst))))
    # Use genexp with min() to find lowest and its index.
    # (Use '_' for variable name for the actual value; we don't use it.)
    _, i_min = min(genexp)
    # Adjust index to be correct in full list.
    i_min += i_sortpos
    # Swap the number at i_sortpos with the lowest found.
    lst[i_sortpos], lst[i_min] = lst[i_min], lst[i_sortpos]

print(lst)
于 2013-03-05T23:01:20.367 回答
1
def selectionSort(List_):
    for i in range(len(List_)):`
        #track the current smallest value
        smallIndex = i
            #loop from the current smallest value
            for j in range(i+1,len(List_))
                if List_[j] < List_[smallIndex]:
                    #if new value is less that our smallest value,change 
                    #smallest value to this
                    smallIndex = j
            if smallIndex != i:
                #swap the values
                List_[smallIndex],List_[i] = List_[i],List_[smallIndex]
    #return sorted list
    return List_
于 2017-11-01T09:54:08.397 回答
0
def ss(l):    
    for i in range(0,len(l)):
        d=l.index(min(l[i:]))        
        c=l[i]
        l[i]=min(l[i:])
        l[d]=c
        print(l)  #it prints each step of selection sort
y=[10,9,1,5,0,6]
ss(y)
于 2015-10-18T21:05:04.563 回答
0
def selSort(L):
    """
    Find the smallest element in the list and put it (swap it) in the first location, 
    Find the second element and put it (swap it) in the second locaiton, and so on. 

    """
    for i in range(len(L) - 1):
        minIndx = i
        minVal= L[i]
        j = i + 1
        while j < len(L):
            if minVal > L[j]:
                minIndx = j
                minVal= L[j]
            j += 1
        temp = L[i]
        L[i] = L[minIndx]
        L[minIndx] = temp 
    return L

称呼:

print( selSort([120,11,0,1,3,2,3,4,5,6,7,8,9,10]) )

输出

[0, 1, 2, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11, 120]
于 2017-01-03T20:07:20.510 回答
0
s = [1,8,4,9,3,6,2]
for i in range(len(s)):
    maxi = max(s[0:len(s)-i])     #find max element
    tempi = s.index(maxi)         # find index of max element
    temp = s[len(s)-1-i]          #assign last element as temp
    s[len(s)-1-i] = maxi          #put max element in last position
    s[tempi] = temp               # put the element initially at last in its new 

print s    
于 2017-02-13T10:36:46.970 回答
0

找到位置(第一个和最后一个),如果最后一个较低,则交换元素。

nums = [4,2,1,10,5,3,100]
def sort(nums):
     ###Find the position and now first 0th element is sorted and rest is unsorted
    #Second iteration first 2 element is sorted
    for i in range(len(nums)-1):
        miniposition = i
        for j in range(i,len(nums)):
            if nums[j] < nums[miniposition]:
                miniposition = j
        temp = nums[i]
        nums[i] = nums[miniposition]
        nums[miniposition] = temp
sort(nums)
print (nums)

第一次迭代(交换 4 和 1) [1, 2, 4, 10, 5, 3, 100]

[1, 2, 4, 10, 5, 3, 100]
[1, 2, 3, 10, 5, 4, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]
[1, 2, 3, 4, 5, 10, 100]

另一种方式

nums = [4,2,1,10,5,3,100]
i = 0
while i<len(nums):
    #smallest element in the sublist
    smallest = min(nums[i:])
    #index of smallest element
    index_of_smallest = nums.index(smallest)
    #swapping
    nums[i],nums[index_of_smallest] = nums[index_of_smallest],nums[i]
    i=i+1
print (nums)
于 2019-09-27T05:13:39.290 回答
0

提供的解决方案略有不同

def selection_sort(l):
i = 0
while i < len(l):
    minium_value = min(l[i:]) # minium value at ith iteration
    minium_value_index = l[i:].index(minium_value) # minium value index at i th iteration

    if minium_value < l[i]: # if the current value already min, skip
        l[i + minium_value_index] = l[i] # put current value in min value's index - swap 1
        l[i] = minium_value # set current value with min value- swap 2
    i += 1

return l
于 2021-07-17T17:47:24.217 回答
0

def selection_sort_min(): # 排序数

for i in range(len(num)-1):
    current_min_index = i
    for j in range(i+1,len(num)):
        if  num[j] < num[current_min_index] :
            current_min_index = j
    num[i],num[current_min_index] = num [current_min_index],num[i]
print(num)

数字 = [23,89,12,0,3,7,33]

selection_sort_min()e

于 2021-08-25T03:20:42.530 回答
-1

这是我认为对数字列表进行排序的好方法,希望对您有所帮助:

list=[5,4,3,1,6,8,10,9]
listsorted=[]
for i in range(len(list)):
    x=min(list)
    list.remove(x)
    listsorted.append(x)
print listsorted 

结果将是 [1, 3, 4, 5, 6, 8, 9, 10]

于 2016-02-19T21:36:25.117 回答
-1

我认为这里的“接受”答案没有帮助。如果我们看一下

mini = min(source[i:]) #find minimum element
min_index = source[i:].index(mini) #find index of minimum element

这不仅在不必要地创建列表切片方面效率低下,而且不必要地搜索它们。它相当简洁,但我认为这不是最好的解决方案。

于 2017-10-28T17:54:28.917 回答
-2
def Selection_Sort(Sarray):
    length = len(Sarray)
    i = 0
    j = 0
    for i in range(length):
        j = i+1
        for j in range(length):
            if Sarray[i] < Sarray[j]
                t = Sarray[i]
                Sarray[i] = Sarray[j]
                Sarray[j] = t
        j = j+1
        i = i+1

    return Sarray
于 2015-04-16T10:18:37.130 回答
-2

麻省理工学院在线课程的选择排序代码。

def selSort(L):
    for i in range(len(L) - 1):
        minIndx = i
        minVal = L[i]
        j = i+1
        while j < len(L):
            if minVal > L[j]:
                minIndx = j
                minVal = L[j]
            j += 1
        if minIndx != i:
            temp = L[i]
            L[i] = L[minIndx]
            L[minIndx] = temp
于 2015-07-16T08:35:53.437 回答
-2
def selectSort(L):
  for i in range(len(L)):
    print L
    minIndex = i
    minValue = L[i]
    j = i + 1
    while j < len(L):
        if minValue > L[j]:
            minIndex = j
            minValue = L[j]  
        j +=1
    temp = L[i]
    L[i] = L[minIndex]
    L[minIndex] = temp
于 2015-08-25T05:07:04.880 回答