Code evolution starting with Quick sort

Source: Internet
Author: User

Note: This article does not discuss the optimization of fast sorting.

Recently in the revision algorithm. Just see the quick sort.

With 3 versions of the improvements, slowly added the template skills. This should also be a harvest.

First version: Test correctness.

Sort by comparing an array of int.

int Dosort (int* collection, int left, int. right) {int newright;        if (left < right) {newright = Dopartition (collection, left, right);        Dosort (collection, left, newright);    Dosort (collection, Newright + 1, right); } return 0;}         BOOL Findmidvalue (int& ExA, int& ExB, int& exc,int& result) {if (EXA&GT;EXB) {if (EXB&GT;EXC)            {result = ExB;        return true;            } if (exa>exc) {result = ExC;        return true;        } result = ExA;    return true; } return false;} void Doquerymidvalue (int* collection,int example1,int example2,int example3,int& result) {int& ExA = Collection    [Example1];    int& ExB = Collection[example2];    int& ExC = Collection[example3];     if (Findmidvalue (Exa,exb,exc,result)) return;    if (Findmidvalue (Exa,exc,exb,result)) return;    if (Findmidvalue (Exb,exa,exc,result)) return; if (Findmidvalue (exb,exc,exa,reSult)) return;    if (Findmidvalue (Exc,exa,exb,result)) return;            if (Findmidvalue (Exc,exb,exa,result)) return; result = ExA;}    int dopartition (int* Collection,int left, int. right) {int cmpvalue;    int example1 = (rand ()% (Right-left + 1)) + left;    int example2 = (rand ()% (Right-left + 1)) + left;            int example3 = (rand ()% (Right-left + 1)) + left;    Doquerymidvalue (Collection,example1,example2,example3,cmpvalue);    left--;    right++;        while (1) {do {right--;                   } while (Collection[right] > Cmpvalue);        do {left++;                   }while (Collection[left] < cmpvalue);        if (left >= right) {break;            } else {int ntemp = Collection[left];            Collection[left] = Collection[right];        Collection[right] = ntemp; }} return right;}

Second version: Supports generics.

If I want to support string, I can't write another version, so the second version solves the problem of changing data types.

Use vectors instead of the original array.

#include "stdafx.h" #include <xstddef> #include <algorithm> #include <vector> #include <stdlib.h >namespace bsp{Template<class t> class QuickSort {public:int Sort (STD::VECTOR&L T    T >& collection);          Private:int Dosort (std::vector< T >& Collection,int left, int.);                int dopartition (std::vector< T >& Collection,int left, int. right);        void Doquerymidvalue (std::vector< T >& collection,int example1,int example2,int example3,t& result);        BOOL Findmidvalue (t& ExA, t& ExB, t& exc,t& result);    }; Template<class t> int Quicksort<t>::sort (std::vector<t>& collection) {return dosor    T (Collection,0,collection.size ()-1);    } template<class t> int quicksort<t>::d osort (std::vector<t>& Collection,int left, int. right)        {int newright; if (left < right)        {newright = Dopartition (collection, left, right);            Dosort (collection, left, newright);        Dosort (collection, Newright + 1, right);    } return 0;    } template<class t> bool Quicksort<t>::findmidvalue (t& ExA, t& ExB, t& exc,t& result)                {if (EXA&GT;EXB) {if (exb>exc) {result = ExB;            return true;                } if (exa>exc) {result = ExC;            return true;            } result = ExA;        return true;    } return false; } template<class t> void quicksort<t>::d oquerymidvalue (std::vector< T >& collection,int exampl        E1,int example2,int example3,t& result) {t& ExA = Collection[example1];        t& ExB = Collection[example2];        t& ExC = Collection[example3]; if (Findmidvalue (exa,exb,exc,result)) retUrn        if (Findmidvalue (Exa,exc,exb,result)) return;        if (Findmidvalue (Exb,exa,exc,result)) return;         if (Findmidvalue (Exb,exc,exa,result)) return;        if (Findmidvalue (Exc,exa,exb,result)) return;                if (Findmidvalue (Exc,exb,exa,result)) return;    result = ExA; } template<class t> int quicksort<t>::d opartition (std::vector<t>& collection,int left, int rig        HT) {T cmpvalue;        int example1 = (rand ()% (Right-left + 1)) + left;        int example2 = (rand ()% (Right-left + 1)) + left;                int example3 = (rand ()% (Right-left + 1)) + left;        Doquerymidvalue (Collection,example1,example2,example3,cmpvalue);        left--;        right++;            while (1) {do {right--;                       } while (M_pfngreater (Collection[right], cmpvalue));            do {left++; }while (M_pfnless (Collection[left], CMPValue));            if (left >= right) {break;                        } else {Std::swap (collection[left],collection[right]);    }} return right; }}

Second version B: supports a custom structure.

The type of the underlying type INT,STL string is built into the comparison function. So you can compare directly.

But the custom type is not recognized by the compiler.

The second version does not move, and the custom structure needs to be overloaded with operator.

typedef struct student{    std::string name;    int year         ;          BOOL operator > (const struct student& DST) const    {        printf ("ref greater \ n");        return this->year > dst.year;    }    BOOL operator < (const struct student& DST) const    {        printf ("ref less \ n");        return This->year < dst.year;    }} Student;

Third version: Support shared_ptr.

The previous version needs to hold the entity, which has a significant impact on performance.

So the introduction of shared_ptr. At this point the comparison function is a comparison of the shared_ptr, not the actual object.

Therefore, you need to add a custom comparison function.

You first need to provide the default comparison function object. This allows the default type to be set without coercion.

Template<class T        ,class _qsless = std::less<t>
        ,class _qsgreater = std::greater<t>
> class QuickSort {public:explicit quicksort<t,_qsless,_qsgreater> () {M_PFNL            ESS = _qsless ();        M_pfngreater = _qsgreater ();    } public:int Sort (std::vector< T >& collection);          Private:int Dosort (std::vector< T >& Collection,int left, int.);                int dopartition (std::vector< T >& Collection,int left, int. right);        void Doquerymidvalue (std::vector< T >& collection,int example1,int example2,int example3,t& result);    BOOL Findmidvalue (t& ExA, t& ExB, t& exc,t& result);        Private: _qsless m_pfnless;    _qsgreater M_pfngreater;    }; Template<class T,class _qsless, class _qsgreater> int Quicksort<t,_qsless,_qsgreater>::sort (std::vector& Lt    t>& collection) {return Dosort (Collection,0,collection.size ()-1); } template<class t,class _qsless, class _qsgreater&Gt int quicksort<t,_qsless,_qsgreater>::d osort (std::vector<t>& Collection,int left, int.) {in        T newright;            if (left < right) {newright = Dopartition (collection, left, right);            Dosort (collection, left, newright);        Dosort (collection, Newright + 1, right);    } return 0; } template<class t,class _qsless, class _qsgreater> bool Quicksort<t,_qsless,_qsgreater>::findmidvalue ( t& ExA, t& ExB, t& exc,t& result) {if (M_pfngreater (EXA,EXB)) {if (m_pfngreate                R (Exb,exc)) {result = ExB;            return true;                } if (M_pfngreater (EXA,EXC)) {result = ExC;            return true;            } result = ExA;        return true;    } return false; } template<class t,class _qsless, class _qsgreater> void QUICKSORT&LT;T,_QSLEss,_qsgreater&gt::d oquerymidvalue (std::vector< T >& collection,int example1,int example2,int Example3,T        & result) {t& ExA = Collection[example1];        t& ExB = Collection[example2];        t& ExC = Collection[example3];         if (Findmidvalue (Exa,exb,exc,result)) return;        if (Findmidvalue (Exa,exc,exb,result)) return;        if (Findmidvalue (Exb,exa,exc,result)) return;         if (Findmidvalue (Exb,exc,exa,result)) return;        if (Findmidvalue (Exc,exa,exb,result)) return;                if (Findmidvalue (Exc,exb,exa,result)) return;    result = ExA; } template<class t,class _qsless, class _qsgreater> int quicksort<t,_qsless,_qsgreater>::d opartition (std        ::vector<t>& Collection,int left, int. right) {T cmpvalue;        int example1 = (rand ()% (Right-left + 1)) + left;        int example2 = (rand ()% (Right-left + 1)) + left;           int example3 = (rand ()% (Right-left + 1)) + left;     Doquerymidvalue (Collection,example1,example2,example3,cmpvalue);        left--;        right++;            while (1) {do {right--; }while (M_pfngreater (Collection[right], cmpvalue));

            Do             {                left++;            } while (M_pfnless (Collection[left], cmpvalue));

                       if (left >= right)            {break                      ;            }            else             {                std::swap (collection[left],collection[right]);                        }        }            return right;    }

  

For the consumer, you need to increase the implementation of the comparison function.


struct Studentptrless:public std::binary_function<studentptr, studentptr, bool> { bool operator () ( studentptr& SRC, studentptr& DST) { if (src = = false) return true; if (DST = = false) return false; return * (Src.get ()) < * (Dst.get ()); } }; struct Studentptrgreater:public std::binary_function<studentptr, studentptr, bool> { bool operator ( ) ( studentptr& src, studentptr& DST) { if (src = = false) return false; if (DST = = false) return true; return * (Src.get ()) > * (Dst.get ()); } }; bsp::quicksort< studentptr, studentptrless, studentptrgreater> qsstudentptr;

  

Code evolution starting with Quick sort

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.