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

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值