排序算法(一):基础排序算法(基于暴力的排序算法)

基础排序算法(基于暴力的排序算法)

排序本质:逐步减少逆序对

在基础排序算法中,将待排序序列分为相对有序区与相对无序区。

每次遍历到数组末尾称为一

冒泡排序(无序区-有序区, O ( n 2 ) O(n^2) O(n2),稳定,就地)

算法流程:在每轮中逐个比较相邻项,并将相对最值置后。因此在每轮中,无序区将有 1 1 1个元素进入有序区(最后一轮2个元素同时进入有序区),进入有序区的为无序区当前最值,且进入有序区的元素呈单调性,轮数=有序区元素个数,有序区首元素即为 n − j n-j nj。最后一轮同时将 2 2 2个元素完成排序,因此最多仅需遍历 n − 1 n-1 n1轮。

在这里插入图片描述

vector<int>a(n);
void bubble_sort(){
    for(int i=0;i<n-1;i++)//冒泡轮数=有序区元素个数
    	for(int j=0;j<n-1-i;j++)//当前工作指针 n-1-j:有序区首元素下标
            if(a[j]>a[j+1]) swap(a[j],a[j+1]);//降序为<
}

在这里插入图片描述

选择排序(有序区-无序区, O ( n 2 ) O(n^2) O(n2),不稳定,就地)

算法流程:在每轮中,将无序区中最值元素放到无序区的首位置,无序区首元素成为有序区末尾,因此轮数=无序区首元素下标

在这里插入图片描述

vector<int>a(n);
void choice_sort(){
    for(int i=0;i<n-1;i++){//轮数=无序区首元素下标
        //c
        int min=i;//假定无序区首元素为最值(以最小值为例)
        for(int j=i+1;j<n;j++)//获取无序区最值元素下标
            if(a[j]<a[min]) min=j;
        //cpp
        int min=min_element(a.begin()+i+1,a.end())-a.begin();
        
        swap(a[i],a[min]);//将最小值放在无序区首元素
    }
}

插入排序

直接插入排序(有序区-无序区, O ( n 2 ) O(n^2) O(n2),稳定,就地)

算法流程:对于每轮在有序区中逆序遍历,以寻找无序区首元素的合适插入点。

在这里插入图片描述

vector<int>a(n);
void insert_sort(){
    for(int i=1;i<MAX;i++){//i:轮数=无序区首元素下标(默认a[0]自己即为有序,因此从1开始)
        int temp=a[i],j;
        for(j=i-1;j>=0;j--)//逆序遍历有序区(有序区下标j=i-1)
            if(temp<a[j]) a[j+1]=a[j];
            else break;
        a[j+1]=temp;//a[j+1]>temp>a[j]
    }
}

优化:二分插入排序( O ( n 2 ) O(n^2) O(n2),稳定,就地)

由于有序区已经是有序的,因此寻找插入点时可采用二分优化,但复杂度不变

vector<int>a(n);
void insert_sort(){
    for(int i=1;i<n;i++){
        int temp=a[i];
        //c
        int l=0,r=i-1,m;
        while(l<=r){
			m=l+r>>1;
			if(t<a[m]) r=m-1;
			else l=m+1;
	   } 
       //cpp
       int l=upper_bound(a.begin(),a.begin()+i-1)-a.begin();
        
	   //已找到插入点l
		for(int j=i-1;j>=l;j--) a[j+1]=a[j];
		a[l]=t;
    }
}
posted @   椰萝Yerosius  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示