冒泡排序
总体思路:冒泡就是一个上浮的过程。每次排好最后的元素,这个算法可以作一点小的优化,标记每一趟是否交换过,如果没有则说明已排好序。只需进行len-1趟操作,因为最后一趟是已排好序的。
例如 :5,3,6,1,4,2
第一趟:3,5,1,4,2,6;
第二趟:3,1,4,2,5,6;
第三趟:1,3,2,4,5,6;
第四趟:1,2,3,4,5,6;
第五趟:由于标记没变,说明已排好序,退出即可。
代码
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int a[6]={5,3,6,1,4,2};
int len=6;
for(int i=1;i<len;i++)
{
bool flag=true;//标记每一趟是否交换过,如果没有交换则已排好序
for(int j=0;j<len-i;j++)
if(a[j]>a[j+1])
{
swap(a[j],a[j+1]);
flag=false;
}
if(flag) break;
}
for(int i=0;i<len;i++) printf("%d ",a[i]);
return 0;
}
空间复杂度O(1),时间复杂度为O(n²),稳定的排序。
应用:https://blog.csdn.net/qq_45249273/article/details/104504462
选择排序
总体思路:
1.每趟起始选取mi=i为最小元素的位置
2.依次往后找,知道有比a[mi]还小的数,则将他的位置赋值给mi,
3.每趟的最后交换a[i]和a[mi]即可。
例如:5,3,6,1,4,2
原始值:5,3,6,1,4,2
第一趟:1,3,6,5,4,2
第二趟:1,2,6,5,4,3
第三趟:1,2,3,5,4,6
第四趟:1,2,3,4,5,6
…
这个代码没有优化,只能全部比对完。
代码
#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
int a[6]={5,3,6,1,4,2};
int len=6;
for(int i=0;i<len-1;i++)
{
int mi=i;//将i当作每趟的最小值,依次寻找,如果有更小的则赋值给mi,一趟结束后判断有否有更小值
for(int j=i+1;j<len;j++)
if(a[j]<a[mi])
mi=j;
if(i!=mi) swap(a[mi],a[i]);//找到最小值,交换
}
for(int i=0;i<len;i++) printf("%d ",a[i]);
return 0;
}
空间复杂度O(1),时间复杂度为O(n²),不稳定的排序。
插入排序
总体思路:将第1个元素设定为有序序列,2到n属于没排序序列,每次将第i个元素插入到(1,i-1)的相应位置。插入到第一个比他小的第一个元素后面即可。
例如:5,3,6,1,4,2
第一趟:3,5,6,1,4,2
第二趟:3,5,6,1,4,2
第三趟:1,3,5,6,4,2
第四趟:1,3,4,5,6,2
第五趟:1,2,3,4,5,6
代码:
#include<stdio.h>
int main()
{
int a[6]={5,3,6,1,4,2};
int len=6;
for(int i=1;i<len;i++)
{
int temp=a[i],j=i;
while(j>0 && temp<a[j-1])//满足后面一个比前面一个小才进行插入
{
a[j]=a[j-1];//大的数往后移
j--;
}
a[j]=temp;//找到恰当位置
}
for(int i=0;i<len;i++) printf("%d ",a[i]);
return 0;
}
空间复杂度O(1),时间复杂度为O(n²),稳定的排序。
总结,如果数组元素较小的话,用插入排序更好。以上排序都属于内部排序。