排序算法总结1--冒泡排序&快速排序

前言:排序算法是算法中非常重要的一个分支,主要包括有以下十类:归并排序,快速排序,堆排序,桶排序,希尔排序,冒泡排序,插入排序,计数排序,选择排序,基数排序。

先放上每个算法的性能分析与时间复杂度:

今天先介绍冒泡排序与快速排序算法

 

1.冒泡排序(时间复杂度O(n^2))

(1)代码实现

#include<iostream>
using namespace std;
int main(){
	int a[]={1,3,9,6,8,5,7,8,19};int temp;
	for(int i=0;i<9-1;i++){//比较n-1轮(n是元素个数)
	   for(int j=0;j<9-1-i;j++) {//比较n-1-i轮 
	   	if(a[j]>a[j+1]){
	   	  temp=a[j];
	   	  a[j]=a[j+1];
	   	  a[j+1]=temp;
	   }
	}
} 
	for(int i=0;i<9;i++)
	   cout<<a[i]<<' ';
} 

 

 (2)浅析代码

先初始化一维数组,然后开始排序,从第一个数开始,每一轮都是第一个数开始与相邻的数进行比较,大的则下沉,小的则上浮,即两数交换。从最坏情况考虑,即原数组降序序存储,则最多比较n-1次(n是数组元素个数)。例如该题,每轮比较依次是:

第一轮:1,3,6,8,5,7,8,9,19

第二轮:1,3,6,5,7,8,8,9,19

第三轮:1,3,5,6,7,8,8,9,19

不难发现,仅三轮就排序完成。

(3)总结:总的来说该算法时间复杂度较高,数组元素较多时可能会超时,因此我们接下来看看快速排序算法。

2.快速排序(时间复杂度O(Olgn))

(1)代码实现

 

#include<iostream>
using namespace std;
void QUICKSORT(int a[],int,int);
int partition(int a[],int,int);
int main(){
    int len;
    cout<< "the previous number is:";
    int A[]={8,45,6,7,29,35,14,30};
    len=sizeof(A)/sizeof(int);
    for(int k=0;k<len;k++)
       cout<<A[k]<<",";
       cout<<endl;
    QUICKSORT(A,0,len-1);
    cout<<"the new number is:";
    for(int i=0;i<len;i++)
       cout<<A[i]<<",";
    return 0;
}
int partition(int a[],int p,int r){//隔断
        int x;
        x=a[p];//设置初始元素为枢纽
        while(p<r){
        while(p<r&&a[r]>=x){//从右向左找比枢纽小的数放左边
            r--;
        }
        a[p]=a[r];
        while(p<r&&a[p]<=x){//从左向右找比枢纽大的数放右边
            p++;
        }
        a[r]=a[p];
        }
    a[p]=x;
    return p;
}
void QUICKSORT(int a[],int p,int r){//快速排序递归调用
    if(p<r){
        int x=partition(a,p,r);
        QUICKSORT(a,p,x-1);
        QUICKSORT(a,x+1,r);
    }
}

 

 (2)浅析代码

这里为了方便了解快速排序的具体实现,写了隔断和递归函数方便理解。这两个函数也是快速排序的核心。接下来介绍代码的核心思想。首先初始化一个一维数组,其次找一个枢纽元素,这里选取第一个元素为枢纽赋值给x。其次遍历剩余数组中的元素,小的数放在枢纽左边,大的数放右边,这里还用到了双指针思路,即p,r两个指针向中间移动,当不满足条件p<r时,循环结束。此时数组已完成隔断。接下来我们不难发现此时枢纽左右元素还是没有按序排列,因此当数组全部都能按着这样隔断,那就实现数组的排序。即每一个元素都满足了隔断的性质。因此我们想到了递归思想,即对枢纽左边和右边重复调用partition函数,最终可实现快速排序算法。具体实现过程如下:(以代码中测试用例为例)

第一步:7,枢纽,6,45,29,35,14,30

第二步:7,6,枢纽,45,29,35,14,30

第三步:7,6,8,45,29,35,14,30

这是第一次调用partition函数得到的结果,下面我们分别对两边函数递归调用

第四次:6,7,8,30,29,35,14,45

第五次:6,7,8,14,29,30,35,45

最终经过五次快速排序算法完成。

(3)总结:了解过快速排序算法后,可以发现这个代码其实还不够简洁,因此熟练掌握后我们可以·通过二分法来实现快速排序,下面通过洛谷的一道题来展示

洛谷--P1177【模版】快速排序

题目描述

利用快速排序算法将读入的 NN 个数从小到大排序后输出。

快速排序是信息学竞赛的必备算法之一。对于快速排序不是很了解的同学可以自行上网查询相关资料,掌握后独立完成。(C++ 选手请不要试图使用 STL,虽然你可以使用 sort 一遍过,但是你并没有掌握快速排序算法的精髓。)

输入格式

第 11 行为一个正整数 NN,第 22 行包含 NN 个空格隔开的正整数 aiai,为你需要进行排序的数,数据保证了 AiAi 不超过 109109。

输出格式

将给定的 NN 个数从小到大输出,数之间空格隔开,行末换行且无空格。

代码展示:

 

#include<bits/stdc++.h>
using namespace std;
int n,a[1000001];
void mysort(int l,int r)
{
    int mid=a[(l+r)/2];//找中间的数进行2分 
    int i=l,j=r;
    do{
        while(a[i]<mid)
		i++;//找左半部分大于中间数的 
        while(a[j]>mid)
		j--;//找右半部分小于中间数的 
        if(i<=j)
        {
            swap(a[i],a[j]);//换位 
            i++;//左指针右移 
            j--;//右指针左移 
        }
    }
	while(i<=j);
    if(l<j) mysort(l,j);
    if(i<r) mysort(i,r);
}
int main()
{
    int len;
    cin>>len;
    for(int i=0;i<len;i++)
    cin>>a[i]; 
    mysort(0,len-1);//快排 
    for(int i=0;i<len;i++)
       cout<<a[i]<<' ';//输出 
    return 0;
}

 

 以上便是冒泡排序&快速排序的具体介绍,后续将逐一更新剩余的排序算法。

 

 

posted @ 2022-10-31 23:24  curtain_cpp  阅读(182)  评论(0)    收藏  举报