常见排序算法总结(上)

这几天,我(蒟蒻)搞了一下排序算法,感觉收获挺多的,今天就总结一下吧。
常见的排序算法有冒泡排序插入排序桶排序(简化版)快速排序归并排序以及利用C++STL库函数中的sort函数进行排序。
这篇文章就主要介绍前三个,后面的三种实现在下一篇中介绍。

1、冒泡排序

冒泡排序可以说是最基本的排序算法了。它的时间复杂度为O(n^2)。冒泡排序的优点是简单,代码易于实现,缺点是时间复杂度较大,用于大规模数据则容易超时。
***基本思想**:

每次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。*(节选自《啊哈!算法》

所以,对于要排序的N个数,需循环比较N-1次,每次循环找出剩下元素中最大(小)的值。
代码实现:

void BubbleSort()
{
	int i1, i2;
	for(int i1=0;i1<N-1;i1++)//N个数排序,只进行N-1次循环
		for(int i2=0;i2<N-1-i1;i2++)//从剩下的数中挑选最大的
			if (num[i2] > num[i2 + 1])//交换
			{
				int temp = num[i2];
				num[i2] = num[i2 + 1];
				num[i2 + 1] = temp;
			}
}

2、插入排序

插入排序和冒泡排序一样也是初学排序算法时必须掌握的,它的时间复杂度为O(n^2),缺点也是时间复杂度较大,不适合大规模数据。
基本思想:

将数组的第一个数认为是有序数组,从后往前(从前往后)扫描该有序数组,把数组中其余n-1个数,根据数值的大小,插入到有序数组中,直至数组中的所有数有序排列为止。这样的话,n个元素需要进行n-1趟排序!!*!
文字原文链接:https://blog.youkuaiyun.com/weixin_43956598/article/details/90181567;
图片原文链接:https://blog.youkuaiyun.com/qq_41055045/article/details/103463918?utm_source=app

代码实现:

void InsertionSort()//从小到大排列num[0]到num[N-1]
{
	for (int i = 1; i < N; i++)//从倒数第二个元素进行插入排序
	{
		if (num[i] < num[i - 1])//如果当前元素小于前一个元素
		{
			int temp = num[i];
			int i1;
			for (i1=i-1; i1 >= 0; i1--)
				if (num[i1] > temp)//比较和前一个元素的大小
					num[i1 + 1] = num[i1];//使较大元素后移,留出一个空位
				else
					break;
			num[i1+1] = temp;//插入空位
		}
	}
}

3、简化版桶排序

桶排序的算法比较巧妙,代码实现起来简单,且时间复杂度仅为O(n)。桶排序的缺点只能对已知数据范围大小的数据进行排序,且当数据很大时需要浪费较大的内存空间,所以运用范围不是很广。下面我们举个例子来说明简化版桶排序:
例:
已知小明的班上有60名学生,现在知道每个同学的语文成绩X[i](1<=X[i]<=100),请你将语文成绩从大到小排序。(本题用以上算法也可做,但比较麻烦)
分析:
既然我们已经知道了待排序元素的大小范围,所以我们可以申请一个容量为101的数组int A[101]={0};,然后对所有成绩遍历一遍,以成绩X[i]为数组元素A的下标,用A[X[i]]++;记录每个成绩出现的次数。

for(int i=1;i<=60;i++)
	A[X[i]]++;

然后我们从大到小输入排序情况:

for(int i=100;i>=1;i--)
	while(A[i])
		{
			A[i]--;
			printf("%d ",i);
		}

完整代码:

#include<stdio.h>
const int N = 60;//学生数量
int main()
{
	int X[N];
	int A[101] = { 0 };
	for (int i = 0; i < N; i++)
	{
		scanf("%d", &X[i]);//输入
		A[X[i]]++;//统计每个分数出现的次数
	}
	for(int i=100;i>0;i--)//从大到小输出
		while (A[i])
		{
			A[i]--;
			printf("%d ", i);
		}
	return 0;
}

好了,这就是以上三种排序算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值