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个,nums[0],遍历无序区,

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

代码如下

复制代码
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);

稳定排序

相关推荐
AndrewHZ25 分钟前
【复杂网络分析】如何入门Louvain算法?
python·算法·复杂网络·社区发现·community det·louvain算法·图挖掘
AndrewHZ26 分钟前
【图像处理基石】如何基于黑白图片恢复出色彩?
图像处理·深度学习·算法·计算机视觉·cv·色彩恢复·deoldify
POLITE333 分钟前
Leetcode 3.无重复字符的最长子串 JavaScript (Day 4)
javascript·算法·leetcode
Xの哲學40 分钟前
Linux IPC机制深度剖析:从设计哲学到内核实现
linux·服务器·网络·算法·边缘计算
sin_hielo42 分钟前
leetcode 756(枚举可填字母)
算法·leetcode
Jeremy爱编码43 分钟前
leetcode热题子集
算法·leetcode·职场和发展
点云SLAM1 小时前
boost中graph_traits和adjacency_list 的内存布局以及最小图示例
数据结构·数据库·图论·boost库·最小图·链接矩阵·graph_traints技术
csg11071 小时前
LORA网络的“最后一公里”难题:当信号被重重阻挡,我们有哪些“方法”来增强覆盖?
单片机·嵌入式硬件·物联网·算法
brave and determined1 小时前
传感器学习(day18):智能手机3D结构光:解锁未来的第三只眼
嵌入式硬件·算法·3d·智能手机·tof·嵌入式设计·3d结构光
CoovallyAIHub1 小时前
当小龙虾算法遇上YOLO:如何提升太阳能电池缺陷检测精度?
深度学习·算法·计算机视觉