快速排序算法及其优化方法

来源:互联网 发布:163邮箱数据库 编辑:程序博客网 时间:2024/05/17 22:15

1、基本快速排序

class QuickSort {public:    void swap(int a[],int i,int j){        int temp=a[i];        a[i]=a[j];        a[j]=temp;    }    int partition(int a[],int low,int high){        int key=a[low];        while(low<high){            //注意以下语句1语句2和语句3语句4的位置不能颠倒,另外语句1和语句3中带有的等号注意别丢失while(low<high&&a[high]>=key){high--;} //语句1            swap(a,low,high); //语句2            while(low<high&&a[low]<=key){low++;} //语句3            swap(a,low,high);//语句4        }         return low;    }    void qSort(int a[],int low,int high){        if(low<high){            int key=partition(a,low,high);            qSort(a,low,key-1);            qSort(a,key+1,high);        }    }    int* quickSort(int* A, int n) {        // write code here        int low=0,high=n-1;        qSort(A,low,high);        return A;    }};

2、速排序算法改进一(三数取中法)
对于快速排序的基本算法,其中取划分值并不一定都能取得最优,不一定每次取得都是中间大小元素,故而对于类似数组a[10]={9,8,7,6,5,4,3,2,1,0}这样的数组效率很低,采用三数取中间大小的方法(每次都取数组最低位置,中间位置,最高位置的三个元素中中间大小的元素作为划分值)对该算法进行优化。

class QuickSort {public:    void swap(int a[],int i,int j){        int temp=a[i];        a[i]=a[j];        a[j]=temp;    }int partition(int a[],int low,int high){    //以下采用三叔取中法对快速排序进行优化    //注意:////和////间为新增代码        int mid=low+(high-low)/2;        if(a[high]>a[low]){            swap(a,low,high);        }                if(a[high]>a[mid]){            swap(a,high,mid);        }        if(a[mid]>a[low]){            swap(a,low,mid);        }        int key=a[low];        ////        while(low<high){            while(low<high&&a[high]>=key){high--;}            swap(a,low,high);            while(low<high&&a[low]<=key){low++;}            swap(a,low,high);         }         return low;     }    void qSort(int a[],int low,int high){        if(low<high){            int key=partition(a,low,high);            qSort(a,low,key-1);            qSort(a,key+1,high);        }    }    int* quickSort(int* A, int n) {        // write code here        qSort(A,0,n-1);        return A;    }};

3、快速排序算法改进二(减少划分值不必要的交换)
该优化方法是通过采用直接赋值的方法从而减少划分值不必要的交换次数,从而达到优化的效果

class QuickSort {public:    void swap(int a[],int i,int j){        int temp=a[i];        a[i]=a[j];        a[j]=temp;    }    int partition(int a[],int low,int high){        int mid=low+(high-low)/2;        if(a[high]>a[low]){            swap(a,low,high);        }                if(a[high]>a[mid]){            swap(a,high,mid);        }        if(a[mid]>a[low]){            swap(a,low,mid);        }        int key=a[low];        while(low<high){            while(low<high&&a[high]>=key){high--;}            a[low]=a[high]; //采用直接复制故而可以减少划分值不必要的交换            while(low<high&&a[low]<=key){low++;}            a[high]=a[low];        }         a[low]=key;//将划分值放置        return low;     }    void qSort(int a[],int low,int high){        if(low<high){            int key=partition(a,low,high);            qSort(a,low,key-1);            qSort(a,key+1,high);        }    }    int* quickSort(int* A, int n) {        // write code here        qSort(A,0,n-1);        return A;    }};

4、快速排序算法改进三
优化小数组时的方案,快速排序存在递归,对于大规模的数据采用快速排序的方法能产生很好的时间效率,但对于规模很小的数组,则采用快速排序很浪费。直接插入排序是简单排序中效率最好的,所以对于小规模的数组,采用直接插入排序。快速排序和插入排序结合使用可以达到很好的效果。

class QuickSort {public:void iSort(int a[],int n){        int i,j,temp;        for(i=1;i<n;i++)        {            if(a[i-1]>a[i])            {                j=i-1;                temp=a[i];                while(j>=0&&a[j]>temp)                {                    a[j+1]=a[j];                    j--;                }                a[j]=temp;            }        }}void insertSort(int a[],int low,int high){        iSort(a+low,high-low+1);}    void swap(int a[],int i,int j){        int temp=a[i];        a[i]=a[j];        a[j]=temp;    }    int partition(int a[],int low,int high){        int mid=low+(high-low)/2;        if(a[high]>a[low]){            swap(a,low,high);        }                if(a[high]>a[mid]){            swap(a,high,mid);        }        if(a[mid]>a[low]){            swap(a,low,mid);        }        int key=a[low];        while(low<high){            while(low<high&&a[high]>=key){high--;}            a[low]=a[high]; //采用直接复制故而可以减少划分值不必要的交换            while(low<high&&a[low]<=key){low++;}            a[high]=a[low];        }         a[low]=key;//将划分值放置        return low;     }    void qSort(int a[],int low,int high){        if((high-low)>MAX_LENGTH_INSERTSORT)        {            int key=partition(a,low,high);            qSort(a,low,key-1);            qSort(a,key+1,high);        }        else        {            insertSort(a,low,high);        }       }    int* quickSort(int* A, int n) {        // write code here        qSort(A,0,n-1);        return A;    }};

5、快速排序算法改进四
对于快速排序存在两次递归操作,很浪费时间和空间,故通过减少递归操作可大大节约时间和空间,采用尾递归的方式,尾递归介绍如下:
这里写图片描述
对于尾递归,编译器可以对其进行自动优化!!!

class QuickSort {public:void iSort(int a[],int n){        int i,j,temp;        for(i=1;i<n;i++)        {            if(a[i-1]>a[i])            {                j=i-1;                temp=a[i];                while(j>=0&&a[j]>temp)                {                    a[j+1]=a[j];                    j--;                }                a[j]=temp;            }        }}void insertSort(int a[],int low,int high){        iSort(a+low,high-low+1);}    void swap(int a[],int i,int j){        int temp=a[i];        a[i]=a[j];        a[j]=temp;    }    int partition(int a[],int low,int high){        int mid=low+(high-low)/2;        if(a[high]>a[low]){            swap(a,low,high);        }                if(a[high]>a[mid]){            swap(a,high,mid);        }        if(a[mid]>a[low]){            swap(a,low,mid);        }        int key=a[low];        while(low<high){            while(low<high&&a[high]>=key){high--;}            a[low]=a[high]; //采用直接复制故而可以减少划分值不必要的交换            while(low<high&&a[low]<=key){low++;}            a[high]=a[low];        }         a[low]=key;//将划分值放置        return low;     }    void qSort(int a[],int low,int high){        if((high-low)>MAX_LENGTH_INSERTSORT)        {            while(low<high)            {                int key=partition(a,low,high);                if(key-low<high-key)//将左数组和右数组长度小的进行递归                {                    qSort(a,low,key-1);                    //qSort(a,key+1,high);                    low=key+1;                }                else                {                    qSort(a,key+1,high);                    high=key-1;                }        }               else        {            insertSort(a,low,high);        }       }    int* quickSort(int* A, int n) {        // write code here        qSort(A,0,n-1);        return A;    }};
0 0
原创粉丝点击