4月5日排序算法总结(1)

冒泡排序

利用每趟都确定出一个最大值或者最小值

如果需要排一个从小到大的数组,那么我们每一趟都要确定一个最大值放在最后,一共有n个数,我们最多需要排列n-1趟就可以了,我们可以改进自己的代码,利用一个flag标记,最初flag为0,当需要发生交换的时候,flag修改成1,。

冒泡的时间复杂度最优的时候为O(n),最差的时候为O(n^2).

稳定性:稳定

接下来我们写一下代码

复制代码
void bubblesort(int*nums,int n){
    for(int i=1;i<=n-1;i++){
        int flag=0;
        for(int j=0;j<=n-1-i;j++){
            if(nums[j]>nums[j+1]){
                swap(&nums[j],&nums[j+1]);
                flag=1;
            }
        }
        if(flag==0){
            return ;
        }
    }
}

排序算法都不需要返回值的。

选择排序

根据排序的名字我们就可以了解到这个排序和选择有关,当然我们需要选择一个最大的或者最小的与待排序数组最后一个发生交换。

每次都要查找最后出待排序数组最大的一个元素,我们采用遍历的形式,最好用index标记最大值的数组下标。

复制代码
void seletsort(int*nums,int n){
    for(int i=1;i<=n-1;i++){
        int maxindex=0;
        for(int j=1;j<n-i;j++){
            if(nums[maxindex]<nums[j]){
                maxindex=j;
            }
        }
        if(maxindex!=n-i){
            swap(&nums[maxindex],&nums[n-i]);
        }
    }
}

时间复杂度O(n^2),在性能上优于冒泡,稳定性:不稳定;

因为当几个相同的元素,在筛选的时候会优先选择前边的先排列,会造成元素之间位置交换,所以选择排序在稳定性上并不稳定。

插入排序

将数组分为有序区和无序区,在未排序的时候数组有序区元素个数为1个,nums0,遍历无序区,

将无序区第一个元素与有序区的元素依次比较,如果无序区元素大于有序区元素,那么不用发生位置变化,如果小于有序区元素,有序区元素就要依次向后移动一位。

代码如下

复制代码
void insertsort(int*nums,int n){
    for(int i=1;i<=n-1;i++){
        int j=i-1;
        int temp=nums[i];
        for(;j>=0;j--){
            if(nums[j]>temp){
                nums[j+1]=nums[j];
            }else{
                break;
            }
        }
        nums[j+1]=temp;
    }
}

时间复杂度:当最好的情况数组本身就是有序的,O(n),

最糟糕的情况O(n^2);

直接插入排序比冒泡选择的性能好一些。

稳定性分析:稳定的

计数排序(桶排序)

望文生义,桶排序就像一个大桶一样把数据都存储进去,我们把数组比喻成了桶,遍历一遍我们的待排序数组,把数组中成功出现的元素,记录在新数组中

这个新数组我们需要利用calloc申请空间,因为calloc申请的数组默认初始化为0,最后记得要释放内存。

一个数可能在待排序数组中出现好多次我们需要解决好这个问题不能遗漏元素。

桶排序不是元素比较而是利用下标来确定元素的正确位置。

代码如下

首先需要一个函数确定待排序数组中最大的元素是几,由此来确定桶的下标范围

复制代码
int maxVal(int* nums, int n) {
	int max = nums[0];
	for (int i = 1; i < n; i++) {
		if (nums[i] > max) {
			max = nums[i];
		}
	}
	return max;
}

void bucketsort(int* nums, int n) {
	int max = maxVal(nums, n);//原数组最大值
	int* bucket = (int*)calloc((max + 1), sizeof(int));
	//用桶计数,记录元素出现的次数
	for (int i = 0; i < n; i++) {
		bucket[nums[i]]++;
	}
	int index = 0;
	for (int i = 0; i < =max ; i++) {
		while (bucket[i]--) {//计数归零的时候停止
			nums[index++] = i;
		}
	}


}

时间复杂度O(n);

空间复杂度O(n);

稳定排序

相关推荐
祖力553 小时前
数据结构的基本概念与单向链表(链表数据类型构造、创建、头插、尾插、头删、尾删)
数据结构·链表
大明者省4 小时前
WSL2 Ubuntu22.04 GPU训练环境配置指南
人工智能·算法·计算机视觉
白狐_7986 小时前
408数据结构第8章:排序②——性质对比秒杀、场景选择与外部排序
java·数据结构·算法
zander2586 小时前
LeetCode 84:柱状图中的最大矩形——单调栈如何确定左右边界
java·数据结构·算法
Shell运维手记7 小时前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
杨航 AI7 小时前
O(n log n):线性对数原理拆解 这个是排序算法的黄金复杂度之一。
算法·排序算法
船厂电气自动化ai大模型8 小时前
AI大模型与数学 第32课 函数凹凸性与二阶导数:拐点求解、凹凸区间计算(10道二阶导数计算题)
数据结构·人工智能·python·深度学习·算法
旖旎夜光8 小时前
LeetCode 3:无重复字符的最长子串(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
叠层归一研究院9 小时前
AGI 系统(十一):二阶网络 — 二阶递归 × 多主体 (元符号网络)
开发语言·人工智能·算法·php·agi
zlinear数据采集卡10 小时前
D223的PWM电机控制:6路独立脉冲+加减速算法深度解析
arm开发·stm32·嵌入式硬件·算法·fpga开发·架构