排序算法学习-快速排序

一.快排简介

快排也叫Quicksort,一般在用快排算法时,都是用的Quicksort当函数名,在c++的algorithm头文件中是自带了排序函数sort()的,用的就是有一定优化的快排算法,那么既然c++可以直接用快排,那为什么我们还要学习呢,因为学习的是思维,是为了我们在学习其他编程语言时也可以用上快排算法,那么我们开始进入正文。

二.快排实现过程

先给大家讲一下c++ sort函数的使用吧。

sort(b+0,b+3);//b是数组名,b+0,b+3是从0到3这个范围进行排序,不包括3,默认是升序
              //如果想是升序,那么可以看看底下给出的函数,可以自己定义升序还是降序

        1)关键数key。快排的实现,首先,你需要一个用于比较的数,我们排序都需要一个参考数来比较谁大谁小,快排也是一样的,我们需要一个关键数Key,一般这个数可以取待排序列的第一个数a[0]。

        2)   从右(end)到左 (sta) 找比key小的数。进行排序的时候,我们最终需要的是,比key大的数都在key的右边,比key小的数都在key的左边,第一次我们从右到左找比key大的数,然后二者交换位置,然后end--。

        3)从左 (sta) 到右 (end) 找比key大的数。同2)的原理,找到以后交换位置,然后sta++。

        4)那么排序什么时候结束呢?就是在sta>=end的时候就结束排序,sta的开始位置是0,end则是待排序列末尾。

        5)那么真的结束了吗?不,这只是第一轮排序结束了,我们结束了第一轮排序以后,key此时的位置是在待排序列中间,以key为界限,我们把待排序列分为两组。分别进行1),2),3)的操作,直到最后无法在分了,那么这时候才是排序真正结束的时候,理论是这样的,那么我们看看代码怎么实现的吧

//平均时间复杂度n*logn
#include <iostream>
#include <string.h>
#include <algorithm>

using namespace std;

struct node{
    int non;
    int x;
    int y;
    int size;
};

node c[1000];//结构体数组

//进行排序重载
bool cmp(node x,node y){
    return x.non>y.non;  
}

bool cmp1(node x1,node y1){
    return x1.non<y1.non;
}


void Quick_Sort(int a[],int sta,int end);//快排函数,待排数组,开始位置,结束位置
void Print_array(int a[],int len);//打印排序后的数组
void Print_structral_body();//打印结构体数组

int main(){
    int a[1000];
    int n;
    cin >> n;//输入待排数量
    int i;
    //开始输入数组
    for(i=0;i<n;i++){
        cin >> a[i];
    }
    for(i=0;i<n;i++){
        cin >> c[i].non >> c[i].x >> c[i].y;
        c[i].size=n;
    }
    Quick_Sort(a,0,n-1);//进行快排
    Print_array(a,n);//打印数组
    sort(c,c+c->size,cmp);//降序
    Print_structral_body();//打印结构体数组
    sort(c,c+c->size,cmp1);//升序
    Print_structral_body();//结构体数组
    system("pause");
    return 0;
}

//打印函数
void Print_array(int a[],int len){
    int i;
    for(i=0;i<len;i++){
        cout << a[i] << " ";
    }
    cout << endl;
}

//打印排序好以后的结构体数组
void Print_structral_body(){
    int i;
    string s="编号:";
    for(i=0;i<c[i].size;i++){
        cout << s << c[i].non << " " << c[i].x << " " << c[i].y << endl;
    }
    cout << endl;
}


void Quick_Sort(int a[],int sta,int end){
    //结束条件
    //当开始位置大于等于结束位置时,快排结束
    while(sta>=end){
        return;
    }
    int k;//设置关键变量
    //用三者取中法对极端数据进行优化,避免退化成冒泡排序
    int b[3];
    b[0]=a[sta];
    b[1]=a[(sta+end)/2];
    b[2]=a[end];
    sort(b+0,b+3);//sort函数是algorithm头文件里面的函数,里面就是快排算法,但是没有经过优化,遇到极端数据退化成冒泡排序
    k=b[1];
    int i=sta;
    int j=end;
    while(i!=j){
        //当i小于等于j,并且a[j]比k大时,可以继续寻找右边比k要小的数
        while(i<j&&a[j]>=k){
            j--;
        }
        //找到以后将关键词k所在位置数与a[j]交换,此时k就等于a[i]
        swap(a[i],a[j]);
        //然后从左边开始找比k要大的数进行交换,此时k就是a[j]
        while(i<j&&a[i]<=k){
            i++;
        }
        //找到以后进行值的交换
        swap(a[i],a[j]);
    }
    //当跳出循环时,说明第一次排序已经结束,那么要将数组以mid为终点,开始进行拆??
    //此时mid就是i,因为最后k所在位置就是a[i]
    Quick_Sort(a,sta,i-1);//前半部分进行快排
    Quick_Sort(a,i+1,end);//后半部分进行快排
}

三.代码简单解释

代码用的c++写的,大部分都有注释帮助大家理解,代码实现了普通待排数组的实现,还有结构体排序的实现,结构体排序的话不能直接用,需要大家进行一个函数定义,来进行降序,还是升序的排列,或者是以某一个数据为基准进行排列

函数代码

//进行排序重载
bool cmp(node x,node y){
    return x.non>y.non;  //以编号为准降序
}

bool cmp1(node x1,node y1){
    return x1.non<y1.non;//以编号为准,升序
}

四.一些优化算法的方法

快排的话,如果确定了数据比较小,那么可以直接用插入排序来实现,此时插入排序是要更快的,第二种的话就是在取关键词上面下手,使用三者取中法,key取a[sta],a[(sta+end)/2],a[end]中,中间那个数的值。

好了,学习笔记大概就到这里,希望对大家有帮助

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值