排序算法总结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;
}
以上便是冒泡排序&快速排序的具体介绍,后续将逐一更新剩余的排序算法。
浙公网安备 33010602011771号