Quicksort算法中的递归函数如何工作?

时间:2017-01-04 03:12:40

标签: c# algorithm quicksort

首先,我一直在寻找这个问题的答案,但我仍然没有找到简单直接的答案。

无论如何,我将要了解Quicksort算法是如何工作的,我已经理解了它的分区如何工作以及为什么它是最好的排序算法之一。但由于我是递归函数的新手(我只知道基本函数),我无法理解下面的代码如何工作。

    static public void SortQuick(int[] arr, int left, int right)
    {
        // For Recursion  
        if (left < right)
        {
            int pivot = Partition(arr, left, right);

            // This "if statement" is for left partition (correct me if i'm wrong)
            if (pivot > 1)
            {
                SortQuick(arr, left, pivot - 1);
            }

            // And this "if statement" is for right partition (again, correct me if i'm wrong)
            if (pivot + 1 < right)
            {
                SortQuick(arr, pivot + 1, right);
            }
        }
    }

我使用Visual Studio断点来理解它的递归,但我仍然感到困惑。我很困惑,为什么当我将第二个“if”语句更改为“else if”时,它的输出正在发生变化,而我很困惑递归的结束。

P.S:我没有放置Partition()方法,因为我已经理解它是如何工作的。

4 个答案:

答案 0 :(得分:0)

我将特别回答问题的第二个“如果”部分。它不可能是“别的”。算法如下:

  • 我可以将您的列表拆分为左半部分右半部分吗?
  • 我有左半边吗?如果我这样做,那么排序左半部分。
  • 我有一个右半边吗?如果我做了一个然后排序右半边。

你不能拥有“else if”的原因是你有“左半部分”和“右半部分”都要排序的场景。

如果分区找不到要排序的较小列表,则递归会自然结束。

如需进一步研究,我推荐YouTube和维基百科。

答案 1 :(得分:0)

递归在较小和较小的列表上重复该过程,直到您获得仅一个项目的列表。

两个if语句正在检查枢轴点是否是列表中最左边或最右边的项目。当它是最左边的pivot =1时,它会停止在左侧制作列表。当它是最右边的pivot+1 = right时,它会停止在右侧制作列表。

当你到达一个项目(最左边和最右边)时,它会再次停止分解。

答案 2 :(得分:0)

您可以参考this site,逐步处理快速排序算法。

  

为什么if而不是else if

这是因为在将一个元素固定在正确的位置后,我们将得到一个left sub-array和一个right sub-array我们需要对两者执行相同的操作,这就是为什么我们采用两个单独的{{1}而不是if

答案 3 :(得分:0)

我做了一个超短的实现,让你明白。看:

void QuickSort(int arr[], int left, int right){
    int pos = (left + right)/2;                  //get middle position of array
    int pivot = arr[pos];                        //stores the value of pivot
    swap(arr[pos], arr[right]);                  //put pivot in the end of array
    int i = left, j = right- 1;                  //initialize pointers

    while(i <= j){
        while(arr[i] < pivot) i++;               //move left
        while(arr[j] >= pivot && j >= i) j--;    //move right
        if(i < j) swap(arr[i++], arr[j--]);      //swap (and walk) if possible
    }

    swap(arr[i], arr[right]);                    //return pivot to right position
    if(i - left) QuickSort(arr, left, i - 1);    //recursion if left subarray isn't empty
    if(right- i) QuickSort(arr, i + 1, right);   //recursion if right subarray isn't empty
}

基本上,递归在分区函数中使用,并且它始终执行左右子阵列不为空。