【问题标题】:Quicksort recursiveness快速排序递归
【发布时间】:2019-02-16 13:46:53
【问题描述】:

我正在尝试在 python 中编写一个快速排序函数,但我在实现它时遇到了麻烦。我理解其中的逻辑,但是我之前从未编写过递归函数。

我查阅了 YouTube 教程,但是他们使用的逻辑通常与我的逻辑不同。

由于它们是进行快速排序的几种方法,因此我将发布我的逻辑。 我的逻辑如下:

  1. 枢轴是列表中随机选择的项目
  2. 枢轴移动到列表中最右边的位置。
  3. 然后将 List 中的每个项目与枢轴进行比较,以查看它是否大于枢轴。
  4. 第一个大于枢轴的项目被指定为 FirstBigNumber。
  5. 然后再次遍历该列表。小于枢轴的第一项将列表中的位置与 FirstBigNumber 交换,Swapped=True
  6. 然后找到一个新的 FirstBigNumber
  7. 重复步骤 4、5、6,直到到达枢轴。
  8. 用 FirstBigNumber 交换枢轴。
  9. 应该对列表进行排序。

我的代码:

import random
List=[3,5,1,7,2,8]
pivot_pos=0
def getpivot(List):
    #Get pivot position
    pivot_pos=random.randint(0,len(List)-1)
    return pivot_pos

def quicksort(List,pivot_pos):
    #Calling Get Pivot function
    getpivot(List)
    print(List)
    #Obtain pivot
    pivot=List[pivot_pos]
    print("Pivot is ",pivot)
    #Swap pivot to right of list
    List[len(List)-1],List[pivot_pos]=List[pivot_pos],List[len(List)-1]
    Swapped=True
    print(List)
    #Loop through List
    for j in range(0,len(List)-1):
        print("Checking if",List[j],"is bigger than",pivot)
        #Marks first num larger than
        if List[j]>pivot and Swapped==True:
            #FirstBigNum stores the index of the First number bigger than pivot
            FirstBigNum=List[j]
            IndexOfBigNum=j
            print("BigNum is",FirstBigNum)
            #This new Big number has not been swapped
            Swapped=False
        for i in range(0,len(List)-1):
            if List[i]<pivot:
                    #Swap the index of smaller num with first big num
                    print("Swapped",List[i]," with ",List[IndexOfBigNum])
                    List[IndexOfBigNum],List[i]=List[i],List[IndexOfBigNum]
                    print(List)
                    Swapped=True
            elif List[i]<pivot:
                print("Pivot is bigger than",List[i])
                #If Value greater than pivot
                pass
            elif i == (len(List)-1):
                #We have reached the end of the List
                #So we need to swap the pivot with the FirstBigNum
                List[FirstBigNum],List[i]==List[i],List[FirstBigNum]
                print("Here")
                print(List)
            else:
                #Is equal to pivot
                pass

getpivot(List)
quicksort(List,pivot_pos)

我收到的输出是:

[5, 8, 7, 2, 1, 3] 

我应该得到的输出是:

[1, 2, 3, 5, 7, 8]   

【问题讨论】:

  • 你没有在任何地方使用递归,quicksort() 不会在任何地方调用quicksort()
  • getpivot() 应该实现什么?您永远不会使用该函数的返回值。所以你使用 global 变量pivot_pos,它始终保持在0
  • 你实际上打印选择的枢轴位置,你注意到它总是打印0吗?
  • 调用getpivot(List) 并没有修改pivot_pos 的全局值的效果(无论如何也不建议修改全局变量)。您似乎对函数调用在 Python 中的工作方式有一个基本的误解。也许你应该在尝试实现快速排序之前澄清你对函数的理解。
  • 接下来,您实际上并没有实现快速排序。快速排序中没有“第一个大值”指针。在快速排序中,您选择一个枢轴,每个较小的值都保留在枢轴之前,每个较大的值都在枢轴之后移动。因此,您可以处理数组中的 all 元素。然后,您将数组分成两个子数组,并对每个子数组应用相同的算法。

标签: python python-3.x quicksort


【解决方案1】:

这是使用 Lomuto 分区递归的快速排序的标准实现。我包含了一个带有随机列表的主驱动程序,因此您可以对其进行测试:

import random


def quick_sort(a, l=0, r=None):
    # Recusrion requires a Base Case
    if r is None :
        r = len(a) - 1
    if l >= r :
        return 0
    # If the Base Case is not encountered then proceed to partion
    s = lomuto_partition(a, l, r)
    # call quicksort recursively
    quick_sort(a, l, s-1)
    quick_sort(a, s+1, r)
    return a


def lomuto_partition(a, l, r):
    p = a[l]
    s = l
    for i in range(l+1, r+1) :
        if a[i] < p :
            s += 1
            a[s], a[i] = a[i], a[s]
    a[l], a[s] = a[s], a[l]
    return s


def random_seq(n=10, lo=0, hi=100):
    seq = []
    for i in range(n):
        seq.append(random.randint(lo, hi))
    return seq


if __name__ == '__main__' :
    n = 16
    print('n:', n)

    a = random_seq(n)
    print("Unsorted Random List: ", a)

希望对你有帮助

【讨论】:

    猜你喜欢
    • 2020-08-14
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2020-04-18
    相关资源
    最近更新 更多