如何按照可汗学院的例子来解决这个迭代快速排序实施的征服步骤?

时间:2017-06-03 19:32:39

标签: algorithm python-3.x quicksort divide-and-conquer

出于教育目的,我正在尝试学习快速排序算法。我没有在网上查看实施或尝试直接从wikipedia上的伪代码实施,而是尝试了一种“艰难的方式”#34;方法

我在CS50 https://www.youtube.com/watch?v=aQiWF4E8flQ&t=305s观看了这个讲座,以便了解这些数字在被快速排序的情况下如何移动"。我将在下面展示的实现完美地适用于视频中提供的示例。初始未排序数组的视频示例如下:

enter image description here

这是我在Python 3中的代码:

len_seq = int(input())

print("len_seq",len_seq)

seq_in = list(map(int,(input()).split()))

print("seq_in",seq_in)

def my_quick_sort(seq):

    wall_index = 0

    pivot_corect_final_index_list = [] 

    while wall_index<len_seq:

        pivot = seq[-1]
        print("pivot",pivot)

        print("wall_index",wall_index)

        for i in range(wall_index,len_seq):
            print ("seq[i]",seq[i])
            if seq[i]<pivot:
                print("before inside swap,", seq)
                seq[wall_index],seq[i]=seq[i],seq[wall_index]
                print("after inside swap,", seq)
                wall_index = wall_index + 1
                print ("wall_index",wall_index)

        print("before outside swap,", seq)

        seq[wall_index],seq[-1]=seq[-1],seq[wall_index]
        print("after outside swap,", seq)

        pivot_corect_final_index = wall_index
        print ("pivot correct final index",pivot_corect_final_index)

        pivot_corect_final_index_list.append(pivot_corect_final_index)
        print ("pivot_corect_final_index_list",pivot_corect_final_index_list)

        wall_index = wall_index + 1
        print ("wall_index",wall_index)


    return seq

print(my_quick_sort(seq_in))

要在我的代码中使用哈佛的CS50示例,您需要输入:

9
6 5 1 3 8 4 7 9 2

算法工作正常并返回正确的输出:

[1, 2, 3, 4, 5, 6, 7, 8, 9]

继续我的学习,我试图实施可汗学院的例子:https://www.khanacademy.org/computing/computer-science/algorithms/quick-sort/a/overview-of-quicksort

在这种情况下,未排序的列表是:

[9, 7, 5, 11, 12, 2, 14, 3, 10, 6]

您需要在我的代码中输入以下内容才能运行它:

10
9 7 5 11 12 2 14 3 10 6

与哈佛的例子不同,在这种情况下,我的实现并不完美。它返回:

[5, 2, 3, 6, 7, 9, 10, 11, 12, 14]

如您所见,我视为枢轴的所有数字都以正确的位置结束。然而,支点背后的一些数字并不正确。

阅读汗学院的文章似乎我的实施正好在分区步骤。然而,它在征服步骤上是不对的。我试图避免寻找最终的解决方案。我正在努力改进我迄今为止所构建的内容。不确定这是否是最好的方法,但这就是我现在正在尝试的方法。

如何修复征服步骤?是否有必要引入递归方法?我怎么能在内部我的迭代过程中继续这样做? 并且应该在成功处理每个支点后引入该步骤吗?

感谢您耐心阅读这篇长篇文章。

1 个答案:

答案 0 :(得分:0)

无法评论,声誉不够。

在算法的第一轮中,您正确地将所有小于枢轴的元素放置在轴的左侧。但是,由于wall_index的值增加(例如从0增加到1),因此忽略索引为0的最左边的元素(它可能不在正确的位置,因此不应忽略它)。

在Khan学院测试案例中,数字5在第一遍中被放置在最左边的索引处,然后被后续传递忽略,因此它被卡在左边。同样,尝试修改哈佛示例

9
6 5 1 3 8 4 7 2 9

产量

[6, 5, 1, 3, 8, 4, 7, 2, 9]

在第一次分区后,您必须确保将快速排序应用于枢轴左侧和右侧的阵列。例如,在将第一个枢轴(6)放置在Khan示例的正确位置(您标记为外部交换的位置)之后,

[5, 2, 3, 6, 12, 7, 14, 9, 10, 11]
 <--1-->  p  <--------2--------->

您必须将相同的快速排序应用于上图中的子阵列1和2。我建议你首先尝试递归实现,这将使你对算法有所了解,然后尝试迭代地实现它。