插入排序Python时出错

时间:2016-02-01 02:55:04

标签: python sorting insertion-sort

我正在尝试使用python实现插入排序。这是我的代码:

def insertionSort(lst):
    lstSorted = [lst[0]]
    for i in range(1,len(lst)):
        index = len(lstSorted)-1
        while index >= 0:
            if lst[i] > lstSorted[index]:
                lstSorted.insert((index+1),lst[i])
            else:
                lstSorted.insert(index,lst[i])
            index -= 1
    return lstSorted



def main():
    lst = [100,10,10000,1000,1000000,10000]
    sortedLst = insertionSort(lst)
    print(sortedLst)

main()

这是输出:

[10, 10000, 10000, 1000000, 1000, 10000, 10000, 1000000, 1000, 10000, 10000, 1000000, 10000, 10000, 10000, 1000000, 100, 10000, 10000, 1000000, 1000, 10000, 10000, 1000000, 1000, 10000, 10000, 1000000, 10000, 10000, 10000, 1000000]

我意识到我的“index- = 1”存在错误,但我不确定如何修复它。这是一个问题,当它到达:

10, 100, 10000

while循环永远不会被删除,因为index是0,所以while循环再次运行,因此它变为:

10, 10000, 100, 10000

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

发生了什么,每当你执行if并且它通过时,它会在它之前插入元素。 试试这个,

def insertionSort(lst):
    for i in range(1,len(lst)):
        j = i
        while j > 0:
            if lst[j-1] > lst[j]:
                t=lst[j]
                lst[j]=lst[j-1]
                lst[j-1]=t
            j-= 1
    return lst

def main():
    lst = [100,10,10000,1000,1000000,10000]
    sortedLst = insertionSort(lst)
    print(sortedLst)

main()

你正在做的是,如果lst中的元素大于lstSorted中的元素,则在lstSorted元素之后插入lst元素。但是如果它少于你在lstSorted中的元素之前添加它,然后递减索引并再次比较。 所以如果列表是[5,4,3] 第一个循环lstSorted变为[4,5] 但第二个循环变为[3,4,3,5] 您需要做的是选择适当的位置放入lst[i],然后将其插入那里。

因此,如果您需要单独的列表,则可以将脚本修改为

def insertionSort(lst):
    lstSorted = [lst[0]]
    for i in range(1,len(lst)):
        index = i-1
        while index >= 0:
            if lst[i] > lstSorted[index]:
                lstSorted.insert((index+1),lst[i])
                break
            index -= 1
        if index==-1:
                lstSorted.insert(0,lst[i])
    return lstSorted

def main():
    lst = [100,10,10000,1000,1000000,10000]
    sortedLst = insertionSort(lst)
    print(sortedLst)

main()

答案 1 :(得分:0)

您遇到的问题是您在while循环中的重复列表中重复插入相同的值。您只想插入一次(for循环的每个循环),因此您需要稍微更改一下逻辑。

最简单的更改是在第一次break调用后添加insert,然后将else块从if移至while循环(并将插入的索引更改为0)。这使用了一个相对不寻常的Python特性,循环可以有else个块,只有在循环运行完成而没有命中break语句的情况下才会运行。

def insertionSort(lst):
    lstSorted = [lst[0]]
    for i in range(1,len(lst)):
        index = len(lstSorted)-1
        while index >= 0:
            if lst[i] > lstSorted[index]:
                lstSorted.insert(index + 1, lst[i])
                break     # stop the while loop after inserting
            index -= 1
        else:             # if we reached index -1 without breaking, insert at the start
            lstSorted.insert(0, lst[i])
    return lstSorted

您可能会注意到索引insert上的0实际上仍然是index+1,就像其他插入调用一样,因此我们实际上可以将两个案例合并为一个案例。我认为这更优雅:

def insertionSort(lst):
    lstSorted = [lst[0]]
    for i in range(1,len(lst)):
        index = len(lstSorted)-1
        while True:   # loop until a break is reached
            if index < 0 or lst[i] > lstSorted[index]:   # combine both insert cases
                lstSorted.insert(index + 1, lst[i])
                break
    return lstSorted