快速排序算法实现

快速排序算法几种写法。
首先快排的思想是选取一个数来划分数组,这个数左边的数都小于等于它,右边的数都大于等于它。就这样递归的划分数组,最后达到快排的目的。
以下3种方法实现主要区别在于划分数组操作不一样,只要数组划分好了,后面操作都一样。
// 第一种方法,挖坑填坑方法。先选取数组第一个数作为参考数,然后分别设置两个指针i,j。i指向最左端,j指向最右端。首先把数组参考数所在位置挖掉作为当前坑,此时坑所在位置及指针i指向的位置,然后指针 j 开始遍历数组,直到遇到小于等于参考数的元素,将其挖出去填当前指针 i 指向的坑,此时更新新的坑,即指针 j 指向的坑,然后指针 i 向前遍历数组元素,直到找到大于等于参考数的元素,然后将其挖出去填指针j 指向的坑,依次反复,直到指针i与j相遇为止,最后把参考数填最后一个坑。这就是一趟排序结果。

#include<iostream>
using namespace std;
void quicksort(int a[], int left, int right){
    int index = a[left];//choose the left data as a index data
    int i = left;  //从左边开始挖坑,i=left为第一个坑
    int j = right;//指向排序数的两个指针
    if (left >= right)  //注意这里递归结束标志一定是划分数组没有元素为止,只有一个元素返回时不行,因为有可能越界情况出现
        return ;
    while (i < j){
        while (a[j] > index && i < j)
            --j;//从排序数组的右边开始遍历知道找到小于标志位的数
        if (i < j)
            a[i] = a[j];//第j个位置挖坑,挖出来东西填第i个坑
        while (a[i] <= index && i < j)
            ++i;
        if (i < j)
            a[j] = a[i];// 第i个位置挖出东西填第j个位置坑
    }
    a[j] = index;
    // 上面的实现选取左边第一个数为划分标志位,标志位左边的数都小于它,右边都大于等于它
    quicksort(a,left,j-1);
    quicksort(a,j+1,right);
}
int main(){
    int a[]={9,2,3,7,4};
    quicksort(a,0,4);
    for (int i = 0; i < 5; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}

第二种参考数归位方法是从数组左端开始遍历,选取数组最左端的元素作为参考数,并把中点指针指向参考数所在位置,(中点指针指的是其左端的数均小于参考数,其自身及其右端的数均大于等于参考数)如果遇到小于参考数的元素,就将其与中点指针指向的元素交换,并将中点指针向前一步,这样操作下去直到遍历完数组。

#include<iostream>
using namespace std;
void swap( int *a, int*b){
    int c;
    c=*a;
    *a=*b;
    *b=c;
}
void quicksort(int a[], int left, int right){
    int temp = a[left];// 选取左边的数为划分数组的参考标准数
    int j = left + 1;
    int pivot = left; // pivot中间指针,pivot指针之前的数均小于参考数,pivot之后的数均大于等于参考数。
    if (left < right){
        while (j <= right){
            if ( a[j] < temp){
                swap(&a[j],&a[pivot]);
                ++pivot;
            }
            ++j;
        }
        quicksort(a,left,pivot-1);
        quicksort(a,pivot+1,right);
    }
}

int main(){
    int a[]={9,2,3,7,4};
    quicksort(a,0,4);
    for (int i = 0; i < 5; ++i)
        cout<<a[i]<<" ";
    cout<<endl;
    return 0;
}

第一种和第二种方法主要区别就在比较次数不同,第二个相当于逐个冒泡遍历方法,每次都要需要将大数冒泡到后移,增加交换次数,但是挖坑填洞方法比较次数较少,例如9,3,2,7,4一趟排序的话,第一种只需要交换一次,即4与9交换,一趟下来结构为4,3,2,7,9;但是用第二种方法的话要把9往后冒泡,则交换4次,一趟结果为3,2,7,4,9.

第三种方法不用递归实现。
未完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值