2017-02-11 83 views
2

什么信号表示程序说:“好,第一次递归quickSort调用完成;继续第二次递归调用”?递归如何突破第一次递归快速排序调用?

int partition (int arr[], int low, int high) 
{ 
    int pivot = arr[high]; // pivot 
    int i = (low - 1); // Index of smaller element 

    for (int j = low; j <= high- 1; j++) 
    { 
     if (arr[j] <= pivot) 
     { 
      i++; // increment index of smaller element 
      swap(&arr[i], &arr[j]); 
     } 
    } 
    swap(&arr[i + 1], &arr[high]); 
    return (i + 1); 
} 

void quickSort(int arr[], int low, int high) 
{ 
    if (low < high) 
    { 
     int pi = partition(arr, low, high); 
     quickSort(arr, low, pi - 1); 
     quickSort(arr, pi + 1, high); 
    } 
} 

回答

0

您的实际问题根源于Recursion Stack

我们先来了解一下Recursion,它基本上构成了一种方法,它不断调用自己日益小的情况,并且每次都重复相同的非递归过程,直到它达到基本情况,停止。

QuickSort的情况下,递归的基本情况是大小为零或1的列表,它们从不需要排序。如果情况并非如此,那么该数组并不意味着被排序。这就是为什么我们再次调用QuickSort方法两次,使用更小尺寸的数组。

我们在包含A[0] to A[i - 2]的所有元素以及包含元素A[i] to A[A.length - 1]的数组的一侧的数组一侧递归。

为什么我们会漏掉A[i - 1]?简单 - 它已经在它的正确位置。

+0

好的。我是这样理解的:一旦你达到了没有做出另一个递归调用的地步,那么它就会将执行返回到**原始**调用函数。因为它在原来的调用者中,所以它继续经过第一次quickSort递归调用并进入第二次调用。那是对的吗? – John

+0

@AllenEricsson是的。调用恰好是递归的并不重要,因为它与两个'printf'语句的工作方式相同。当第一个呼叫完成时,第二个呼叫被呼叫。这发生在所有的深度,但这与迭代中的一个无关。 – Sylwester

+0

那么其他堆栈帧会发生什么?假设有五个递归调用,第五个调用是当low> = high时。其他四帧会发生什么? – John