Python选择 - 使用while循环排序返回未改变的数组 - 为什么?

时间:2017-06-03 20:59:41

标签: python algorithm debugging selection-sort

我讨厌不得不这样问,但我的斗智尽头。我正在执行此操作的任务需要 while 循环包含在 for 循环中,而不是嵌套 for 循环我曾经能够找到的每个例子都使用过。很沮丧。

所以这里是代码,其中的评论是为了我自己的参考而写出来的,因为我可以理解正在发生的事情(我现在不是一个非常优秀的程序员)。

def selection_sort(arr): 
    for indexvalue in range (0, len(arr) - 1): #we want to start with the 0th item in the index for selection sort and end at the second-to-last one, 
        currentmin = indexvalue #establishes the first variable as our lowest looked at so far. This is something that changes every time we go over the array, looking for the next lowest number 
        while indexvalue<len(arr): 
            if arr[indexvalue] < arr[currentmin]: #allows us to find the new lowest value—anything lower than our currently-located minimum should count as our new lowest value
                arr[indexvalue], arr[currentmin] = arr[currentmin], arr[indexvalue] #exchanges the two values so that our current lowest value is set one to the left in the array, and the new lowest value one to the right
                indexvalue = indexvalue+1 #adds another 1 to our counter so that we can compare the next-indexed items 
            else: #should occur when we reach the end of our array 
                break #forcibly ends the while loop, and by extension the function 

不确定发生了什么 - 最好的可以处理它有效,但显然没有。例如,当我跑:

testlist=[10, 12, 15, 1, 0, 4, 99]
selection_sort(testlist)
print(testlist)

我得到了测试列表,没有改变。知道为什么会这样吗?我显然遗漏了一些重要的东西,但我不知道它可能是什么。

编辑:下面是新的改进代码。不完美,但它现在至少要排序某些东西。这个集合导致一组数据似乎正在用它们的索引位置替换元素;我很确定它是由第6行引起的。不知道为什么会这样。

def selection_sort(arr): 
    for indexvalue in range (0, len(arr) - 1): #we want to start with the 0th item in the index for selection sort and end at the second-to-last one, 
        currentmin = indexvalue #establishes the first variable as our lowest looked at so far. This is something that changes every time we go over the array, looking for the next lowest number 
        while indexvalue<len(arr): 
            if arr[indexvalue] > currentmin: #allows us to find the new lowest value—anything lower than our currently-located minimum should count as our new lowest value
                arr[indexvalue], currentmin = currentmin, arr[indexvalue] #exchanges the two values so that our current lowest value is set one to the left in the array, and the new lowest value one to the right
                indexvalue = indexvalue+1 #adds another 1 to our counter so that we can compare the next-indexed items 
                print (arr)
            else: #should occur when we reach the end of our array 
                break #forcibly ends the while loop, and by extension the function 

2 个答案:

答案 0 :(得分:0)

在您的while循环开始时,您始终将arr[currentmin]与其自身进行比较,因为当时currentmin == indexvalue。由于值永远不会小于自身,else分支将接管并结束while循环,然后才能对列表进行任何更改。
这种情况发生在for循环的每次迭代中,因此会留下未更改的列表。

传入可能的解决方案!

  

要么你在第5行中使用if arr[indexvalue] <= arr[currentmin]:,这完全没问题,因为选择排序不一定是稳定的排序算法

  

在左前方添加indexvalue = indexvalue + 1之类的行 if arr[indexvalue] < arr[currentmin]:

希望它有所帮助(我并没有用所有的格式^^'来覆盖它)

继续:

现在我们已经解决了这个问题,我们应该看看if语句中发生了什么:

当找到一个小于最小元素的元素时,选择排序只会记住这个新索引 currentmin = indexvalue
还不应该进行交换。
indexvalue到达列表末尾时,currentmin应该指向最小的尚未排序的元素。

这个最小的元素现在应该与第一个未排序的元素交换,该元素应该在arr[indexvalue]。但是,由于您已使用indexvalue移动列表的其余部分,因此程序不知道未排序元素的起始位置。你需要在while循环中定义另一个“running-index”,在while循环的头部之前用indexvalue初始化。

答案 1 :(得分:0)

既然你提到你可以从摆弄工作的例子中学到最好的东西:
享受和学习! ;)

def selection_sort(arr): 
    for indexvalue in range (0, len(arr) - 1): #we want to start with the 0th item in the index for selection sort and end at the second-to-last one, 
        indexval2 = indexvalue + 1 #new running-index in order not to lose track of where the unsorted part starts
        currentmin = indexvalue #establishes the first variable as our lowest looked at so far. This is something that changes every time we go over the array, looking for the next lowest number 
        while indexval2 < len(arr): 
            if arr[indexval2] < arr[currentmin]: #allows us to find the new lowest value—anything lower than our currently-located minimum should count as our new lowest value
                currentmin = indexval2 #sets currentmin to the new lowest value
            indexval2 = indexval2 + 1 #adds another 1 to our counter so that we can compare the next-indexed items
        arr[currentmin], arr[indexvalue] = arr[indexvalue], arr[currentmin] #swapping lowest to beginning of unsorted elements. This way it will be neglegted in the next for-iteration