选择排序Python

时间:2013-03-05 22:19:37

标签: python sorting

这可能看起来像一个简单的问题但是当我尝试在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

14 个答案:

答案 0 :(得分:11)

我认为有几个问题。

首先,当你做源[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]

答案 1 :(得分: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)

答案 2 :(得分:4)

或者您可以尝试这种方式:

arr = [5,4,3,1,6,8,10,9] # array not sorted

for i in range(len(arr)):
    for j in range(i, len(arr)):
        if(arr[i] > arr[j]):
            arr[i], arr[j] = arr[j], arr[i]

print arr

答案 3 :(得分: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_

答案 4 :(得分:1)

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

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)

答案 5 :(得分: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)

答案 6 :(得分: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]

答案 7 :(得分: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    

答案 8 :(得分: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

答案 9 :(得分:-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]

答案 10 :(得分:-1)

我认为这里的“接受”答案是无益的。如果我们看看例如。

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

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

答案 11 :(得分:-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

答案 12 :(得分:-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

答案 13 :(得分:-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