Stackoverflow with Quicksort Java implementation

前端 未结 9 1479
一生所求
一生所求 2020-12-06 19:25

Having some problems implementing quicksort in java. I get a stackoverflow error when I run this program and I\'m not exactly sure why. If anyone can point out the error, it

相关标签:
9条回答
  • 2020-12-06 19:32

    This should be quite spot on. Code below with this Image makes way more sense.

    public void quickSort(long[] a){
    
      int startingIndex = 0;
      int endingIndex = a.length - 1;
      qsort(a, startingIndex, endingIndex);
    
    }
    
    private void qsort(long[] a, int startingIndex, int endingIndex){
    
      if (startingIndex < endingIndex){
        int middleIndex = partition(a, startingIndex, endingIndex);
        qsort(a, startingIndex, middleIndex-1);
        qsort(a, middleIndex+1, endingIndex);
      }
    
    }
    
    private int partition(long[] a, int startingIndex, int endingIndex){
      long pivot = a[endingIndex];
      int endWall = endingIndex;
      int wall = 0;
    
      while (wall < endWall){
    
        if (a[wall] < pivot){
          wall++;
        }
        else {
          a[endWall] = a[wall];
          a[wall] = a[endWall - 1];
          a[endWall - 1] = pivot;
          endWall--;
        }
      }
      return wall;
    }
    

    Enjoy!

    0 讨论(0)
  • 2020-12-06 19:34
    public class MyQuickSort {
    
        private int array[];
        private int length;
    
        public void sort(int[] inputArr) {
    
            if (inputArr == null || inputArr.length == 0) {
                return;
            }
            this.array = inputArr;
            length = inputArr.length;
            quickSort(0, length - 1);
        }
    
        private void quickSort(int lowerIndex, int higherIndex) {
    
            int i = lowerIndex;
            int j = higherIndex;
            // calculate pivot number, I am taking pivot as middle index number
            int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
            // Divide into two arrays
            while (i <= j) {
                /**
                 * In each iteration, we will identify a number from left side which 
                 * is greater then the pivot value, and also we will identify a number 
                 * from right side which is less then the pivot value. Once the search 
                 * is done, then we exchange both numbers.
                 */
                while (array[i] < pivot) {
                    i++;
                }
                while (array[j] > pivot) {
                    j--;
                }
                if (i <= j) {
                    exchangeNumbers(i, j);
                    //move index to next position on both sides
                    i++;
                    j--;
                }
            }
            // call quickSort() method recursively
            if (lowerIndex < j)
                quickSort(lowerIndex, j);
            if (i < higherIndex)
                quickSort(i, higherIndex);
        }
    
        private void exchangeNumbers(int i, int j) {
            int temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }
    
        public static void main(String a[]){
    
            MyQuickSort sorter = new MyQuickSort();
            int[] input = {24,2,45,20,56,75,2,56,99,53,12};
            sorter.sort(input);
            for(int i:input){
                System.out.print(i);
                System.out.print(" ");
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-06 19:37

    Quicksort is slightly sensitive to input that happens to be in the right order, in which case it can skip some swaps. Mergesort doesn't have any such optimizations, which also makes Quicksort a bit faster compared to Mergesort.

    Why Quick sort is better than Merge sort

    0 讨论(0)
  • 2020-12-06 19:38
    int partition(int array[], int too_big_index, int too_small_index)
    {
         int x = array[too_big_index];
         int i = too_big_index;
         int j = too_small_index;
         int temp;
         do
         {                 
             while (x <array[j])
            {
                  j --;
            } 
             while (x >array[i])
             {
                  i++;
             } 
              if (i < j)
             { 
                     temp = array[i];    
                     array[i] = array[j];
                     array[j] = temp;
             }
         }while (i < j);     
         return j;           // middle  
    }
    
    void QuickSort(int num[], int too_big_index, int too_small_index)
    {
          // too_big_index =  beginning of array
          // too_small_index = end of array
    
         int middle;
         if (too_big_index < too_small_index)
        {
              middle = partition(num, too_big_index, too_small_index);
              QuickSort(num, too_big_index, middle);   // sort first section
              QuickSort(num, middle+1, too_small_index);    // sort second section
         }
         return;
    }
    
    
    
    void main()
    {
        int arr[]={8,7,13,2,5,19,1,40,12,34};
    
        QuickSort(arr,0,9);
        for(int i=0;i<10;i++)
             System.out.println(arr[i]);
    }
    
    0 讨论(0)
  • 2020-12-06 19:39

    You might have an unbounded recursion bug on your hands. Not sure from my quick scan of it, but...

    Even if you don't, you're still going to use lots of stack with this implementation. Enough to cause a stack overflow. What happens if you call it with 1 million items that are already sorted? You'll partition them into 1 and 999,999 items, then recurse. So you'll need 1 million stack frames to make this work.

    There are lots of ways to solve this, including recursing on the smaller of the two ranges and iterating on the larger of the two, or implementing the stack yourself in a heap datastructure, etc. You probably want to do even better than that, though, as the deep stack also means you're blowing past the O(n lg n) sorting bound.

    p.s. the bug is here:

    qsort(a, 0, i-2); 
    qsort(a, i, a.length-1); 
    

    should be

    qsort(a, si, i-2);
    qsort(a, i, ei);
    
    0 讨论(0)
  • 2020-12-06 19:49

    //Just implemented the tester class for this and it'll work

    public int[] sort(int[] A, int from, int to ){

    if(from<to){
        int pivot=partition(A,from,to);
        if(pivot>1)
            sort(A,from, pivot-1);
    
        if(pivot+1<to)
            sort(A, pivot+1, to);
    
    
    }
    
    return array;
    

    }

    public int partition(int A[ ], int from, int to){

    while(from < to){
        int pivot=A[from];
    
        while(A[from]<pivot)
            from++;
    
        while(A[to]>pivot)
            to--;
    
    
        if(from<to)   
            swap(A,to,from);
    
    
    
    }
        return to;
    }
    
    private void swap(int A[], int i, int j){
        int temp = A[i];
        A[i] = A[j];
        A[j] = temp;}
    
    0 讨论(0)
提交回复
热议问题