How to optimize quicksort

后端 未结 6 588
再見小時候
再見小時候 2020-12-08 05:51

I am trying to work out an efficient quicksort algo. It works okay, but takes long time to run when the number of elements are huge, and certain sections of the

6条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-08 05:59

    There are multiple ways one can make standard quicksort more efficent. To implement the first tip from your post you should write something like:

    void quicksort(int * tab, int l, int r)
    {
       int q;
       while(l < r)
       {
          q = partition(tab, l, r);
          if(q - l < r - q) //recurse into the smaller half
          {
             quicksort(tab, l, q - 1);
             l = q + 1;
          } else
          {
             quicksort(tab, q + 1, r);
             r = q - 1;
          }
       }
    }
    

    Hope that's clear enough. Next step would be to implement your own stack (or use some built-in from whatever language you are using) instead of using recursive calls. Example (pseudo)code:

    void quicksort2(int * tab, int l, int r)
    {
        int le, ri, q;
        init stack;
        push(l, r, stack);
        while(!empty(stack))
        {
            //take the top pair of values from the stack and set them to le and ri
            pop(le, ri, stack);
            if(le >= ri)
                continue;
            q = partition(tab, le, ri);
            if(q - le < ri - q) //smaller half goes first
            {
                push(le, q - 1, stack);
                push(q + 1, ri, stack);
            } else
            {
                push(q + 1, ri, stack);
                push(le, q - 1, stack);
            }
        }
        delete stack;
    }
    

    Then you can proceed to implement the other tip from your post. To do this you should set some arbitrary constant, lets call it CUT_OFF, to around 20. This will tell your algorithm when it should switch to insertion sort. It should be rather easy (a matter of adding one if-statement) to alter the previous example so that it switches to insertion sort after it's reached a CUT_OFF point so I will leave you to that.

    As for partition method I would recommend using the Lomuto partition instead of Hoare.

    However, if your data is already pre-sorted, then you could consider using a different algorithm altogether. From my experience, natural series merge sort implemented on a linked list is a very good choice, if your data is pre-sorted.

提交回复
热议问题