【问题标题】:How to fix the Conquer step of this iterative quicksort implementation following Khan Academy's example?如何按照可汗学院的示例修复此迭代快速排序实现的征服步骤?
【发布时间】:2017-11-04 23:32:36
【问题描述】:

出于教育目的,我正在尝试学习快速排序算法。我没有在网络上查看实现,也没有尝试直接从 wikipedia 上的伪代码中实现,而是尝试了一种“硬方式”方法。

我从 CS50 https://www.youtube.com/watch?v=aQiWF4E8flQ&t=305s 观看了这个讲座,以了解数字在“快速排序”时如何移动。我将在下面展示的实现非常适合视频中提供的示例。初始未排序数组的视频示例如下:

这是我在 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))

要在我的代码中使用 harvard 的 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]

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

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

如何修复征服步骤?是否有必要引入递归方法?我如何我的迭代过程中做到这一点? 是否应该在成功处理每个枢轴后引入该步骤?

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

【问题讨论】:

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


    【解决方案1】:

    无法评论,声望不够。

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

    在 Khan academy 测试用例中,数字 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 应用相同的快速排序。我建议您先尝试递归实现,这将使您对算法有一个很好的了解,然后尝试迭代实现它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      • 2012-07-31
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      相关资源
      最近更新 更多