这是排序部分的第二篇文章,其他的排序方法可以点击下面的传送门(•͈ᴗ•͈ૢૢ)❊⿻*
- 排序——插入排序(直接插入排序、希尔排序、折半插入排序)
- 排序——交换排序(冒泡排序、快速排序)
- 排序——选择排序(简单选择排序、堆排序)
冒泡排序(bubble sort)
冒泡排序又称起泡排序,基本思想是两两比较相邻记录的关键码,如果反序则交换。
排序过程
- 将整个待排序的记录序列划分成有序区和无序区,初始时有序区为空,无序区包括所有待排序的记录。
- 对无序区从前向后依次将相邻记录的关键码进行比较,若反序则交换,从而使得
关键码小的记录向前移,关键码大的记录向后移(像水中的气泡,体积大的先浮上来) - 重复执行2直到无序区中没有反序的记录。
例如: 待排序序列453,143,49,6,31,1,28
……以此类推,直到整个序列排序完成。例子里可以看出来每次交换都有一个数到达它的最终位置(之后排序这个数字的位置都不会变了嗷₍₍ (ง ˙ω˙)ว ⁾⁾)。
代码
void BubbleSort(int a[],int n)
{
for(int i=0;i<n-1;i++)
{
/*设置一个标志,如果依次循环中不再出现交换,
证明每个记录都到达了它的最终位置上,
即可跳出循环停止排序过程。*/
bool flag=false;
for (int j=0;j<n-i-1;j++)
{
if (a[j]>a[j+1])
{
int mid=a[j];
a[j]=a[j+1];
a[j+1]=mid;
flag=true;
}
}
if(flag==false) return;
}
}
算法分析
/ | 时间复杂度 | 空间复杂度 |
---|---|---|
最好情况 | O ( n ) O(n) O(n) | |
最坏情况 | O ( n 2 ) O(n^2) O(n2) | |
平均 | O ( n 2 ) O(n^2) O(n2) | O ( 1 ) O(1 ) O(1) |
实例
待排序序列453,143,49,6,31,1,28
#include <iostream>
using namespace std;
void Print(int a[],int n)
{
for (int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
void BubbleSort(int a[],int n)
{
for(int i=0;i<n-1;i++)
{
bool flag=false;
for (int j=0;j<n-i-1;j++)
{
if (a[j]>a[j+1])
{
int mid=a[j];
a[j]=a[j+1];
a[j+1]=mid;
flag=true;
}
}
if(flag==false) return;
/*-------排序过程------*/
cout<<"第"<<i+1<<"趟排序:";
Print(a,n);
/*-------排序过程------*/
}
}
int main()
{
int b[7]={453,143,49,6,31,1,28};
cout<<"待排序数组:"<<endl;
Print(b,7);
BubbleSort(b,7);
cout<<"排序结果:"<<endl;
Print(b,7);
return 0;
}
快速排序(quick sort)
排序过程
快速排序是对起泡排序的一种改进,基本思想是首先选一个轴值(pivot即比较的基准)将待排序记录划分成独立的两部分,左侧记录的关键码均小于或等于轴值,右侧记录的关键码均大于或等于轴值,然后分别对这两部分重复上述过程,直到整个序列有序。
举个栗子: 待排序序列:23,12,49,6,31,19,28
以第一行数据为例:
例子中可以看出,每次交换轴值都会到达它的最终位置(之后排序这个数字的位置都不会变了嗷₍₍ (ง ˙ω˙)ว ⁾⁾)。
代码
我参考了两本书,列了两个写法。两个写法的区别就在于int partition(int a[],int low,int high)
这个函数不太一样。
写法一
不借助pivot做暂存空间。每次比较发现逆序之后直接进行交换。
void change(int &a, int &b) //自定义的交换函数
{
int mid=a;
a=b;
b=mid;
}
int partition(int a[],int low,int high)
{
while(low<high)
{
while(low<high && a[low]<=a[high])
high--;
change(a[low],a[high]);
while(low<high && a[low]<=a[high])
low++;
change(a[low],a[high]);
}
return low; //return high也行
}
void QuickSort(int a[],int low,int high)
{
if(low<high)
{
int p=partition(a,low,high);
QuickSort(a,low,p-1);
QuickSort(a,p+1,high);
}
}
写法二
借助pivot做暂存空间。最后再将轴值放入。
int partition(int a[],int low,int high)
{
int pivot = a[low];
while(low<high)
{
while(low<high && a[high]>=pivot)
high--;
a[low]=a[high];
while(low<high && a[low]<=pivot)
low++;
a[high]=a[low];
}
a[low]=pivot;
return low; //return high也行
}
void QuickSort(int a[],int low,int high)
{
if(low<high)
{
int p=partition(a,low,high); //第一次划分
QuickSort(a,low,p-1); //递归对左侧划分
QuickSort(a,p+1,high); //递归对左侧划分
}
}
算法分析
/ | 时间复杂度 | 空间复杂度 |
---|---|---|
最好情况 | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( l o g 2 n ) O(log_2n) O(log2n) |
最坏情况 | O ( n 2 ) O(n^2) O(n2) | O ( n ) O(n) O(n) |
平均 | O ( n l o g 2 n ) O(nlog_2n) O(nlog2n) | O ( l o g 2 n ) O(log_2n) O(log2n) |
实例
/*---------------------写法一-----------------------*/
#include <iostream>
using namespace std;
void Print(int a[],int n)
{
for (int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
void change(int &a, int &b)
{
int mid=a;
a=b;
b=mid;
}
int partition(int a[],int low,int high)
{
while(low<high)
{
while(low<high && a[low]<=a[high])
high--;
//if(low<high)
{
change(a[low],a[high]);
// low++;
}
while(low<high && a[low]<=a[high])
low++;
//if(low<high)
{
change(a[low],a[high]);
// high--;
}
}
Print(a,7); //过程输出
return low; //return high也行
}
void QuickSort(int a[],int low,int high)
{
if(low<high)
{
int p=partition(a,low,high);
QuickSort(a,low,p-1);
QuickSort(a,p+1,high);
}
}
int main()
{
int a[7]={23,12,49,6,31,19,28};
cout<<"待排序序列:"<<endl;
Print(a,7);
cout<<endl<<"划分过程"<<endl;
QuickSort(a,0,6);
cout<<endl<<"排序结果:"<<endl;
Print(a,7);
return 0;
}
/*---------------------写法二-----------------------*/
#include <iostream>
using namespace std;
void Print(int a[],int n)
{
for (int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
int partition(int a[],int low,int high)
{
int pivot = a[low];
while(low<high)
{
while(low<high && a[high]>=pivot)
high--;
a[low]=a[high];
while(low<high && a[low]<=pivot)
low++;
a[high]=a[low];
}
a[low]=pivot;
Print(a,7); //过程输出
return low; //return high也行,可以自己试一下,因为这时候low=high为pivot的最终位置
}
void QuickSort(int a[],int low,int high)
{
if(low<high)
{
int p=partition(a,low,high);
QuickSort(a,low,p-1);
QuickSort(a,p+1,high);
}
}
int main()
{
int a[7]={23,12,49,6,31,19,28};
cout<<"待排序序列:"<<endl;
Print(a,7);
cout<<endl<<"划分过程"<<endl;
QuickSort(a,0,6);
cout<<endl<<"排序结果:"<<endl;
Print(a,7);
return 0;
}