簡體   English   中英

當 N 大於 10K 時,Partition 函數中的 StackOverflowException

[英]StackOverflowException in Partition function when N is greater then 10K

當在QuickSortPartition區內時, 10K有效, 15K導致StackOverflowException

我的主要:

internal class Program
    {
        static void Main(string[] args)
        {
            const int N = 15000;
            const bool M_ORDERED = true;
            Random random = new Random();

            int[] list = (M_ORDERED) ? Enumerable.Range(1, N).ToArray() : Enumerable.Range(1, N).OrderBy(x => random.Next()).ToArray();

            // Capture current time
            Stopwatch watch = new Stopwatch();
            watch.Start();
            QuickSort.Sort(list, N);
            watch.Stop();
            double time = (double)watch.ElapsedMilliseconds / 1000.0;

            String output = String.Format("Size: {0}, Elapsed time: {1:F2} sec", N, time);
            Console.WriteLine(output);
            System.Console.ReadKey();
        }
    }

快速排序.cs

class QuickSort
{
    public static void Sort(int[] a, int n) 
    {
        InternalSort(a, 0, a.Length - 1);
    }

    private static void InternalSort(int[] a, int low, int high) 
    {
        if (high <= low)
            return;

        int j = Partition(ref a, low, high);
        InternalSort(a, low, j - 1);
        InternalSort(a, j + 1, high);
    }

    private static int Partition(ref int[] a, int left, int right) 
    {
        int pivot = a[left];
        while (true)
        {
            while(a[left] < pivot)
                left++;

            while(a[right] > pivot)
                right--;

            if(left < right)
            {
                int temp = a[right];
                a[right] = a[left];
                a[left] = temp;
            } else
            {
                return right;
            }
        }
    }
}

處理此問題的一種常見方法是僅在較短的子分區上遞歸並在較長的子分區上循環。

所以而不是

private static void InternalSort(int[] a, int low, int high) 
{
    if (high <= low)
        return;

    int j = Partition(ref a, low, high);
    InternalSort(a, low, j - 1);
    InternalSort(a, j + 1, high);
}

你做

private static void InternalSort(int[] a, int low, int high) 
{
  while (true) {
    if (high <= low)
        return;

    int j = Partition(ref a, low, high);

    if (((j - 1) - low) < (high - (j + 1))) {
      InternalSort(a, low, j - 1);
      low = j + 1;
    }
    else {
      InternalSort(a, j + 1, high);
      high = j - 1;
    }
  }
}

這可確保您遞歸的分區在每個級別上最多為原始分區大小的一半。 這意味着,例如,任何 1,000,000 個元素的數組都可以使用大約 20 的最大遞歸調用深度進行排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM