十种经典排序算法总结及C++实现

本文详细介绍了十种经典的排序算法,包括冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序、计数排序、桶排序和基数排序。对每种算法,作者提供了算法描述、代码实现和时间复杂度分析,帮助读者理解排序算法的工作原理和优缺点。
摘要由CSDN通过智能技术生成

0.关于排序

相关概念:

  • 稳定 :如果a原本在b前面,而a=b,排序之后a仍然在b的前面。
  • 不稳定 :如果a原本在b的前面,而a=b,排序之后a可能会出现在b的后面。
  • 时间复杂度:执行算法所需要的计算工作量,是关于数据规模n的函数。
  • 空间复杂度:执行算法所需要的内存空间,也是关于数据规模n的函数。
  • 比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序。
  • 非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序。

算法分类:
排序分类
 
算法总结:

排序总结
 
注: 对于稳定的排序算法,在实现过程中要特别注意"<"、">“和”<="、">="的使用,不然可能会导致不稳定。


1. 冒泡排序(Bubble Sort)

  冒泡排序是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越大(或越小)的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
 
算法描述:

  1. 从第一个元素开始依次比较相邻的元素对,若顺序错误则将它们交换。
  2. 当比较完最后一对相邻元素,此时最大(或最小的元素)已经"浮"到元素列末尾。
  3. 对除去最后一个元素的元素列重复1~2,直到没有任何元素对需要比较则排序完成。

冒泡排序
 
代码实现:

vector<int> bubbleSort(vector<int>& nums)
{
   
	int len = nums.size();
	if (!len) return nums;
	for (int i = len - 1; i > 0; i--)
	{
   
		int flag = true;
		for (int j = 0; j < i; j++)
		{
   
			if (nums[j] > nums[j + 1])
				{
   
					swap(nums[j] , nums[j + 1]);
					flag = false;
				}
		}
		if(flag == true)    //如果没有元素进行交换,则代表此时元素已经有序,则不必进行后续比较
			return nums;
	}
	return nums;
}

 
算法分析: 若序列初始状态为正序的,则一趟扫描之后即可结束循环,此时最好时间复杂度为O(n)。若序列初始状态为反序,则共需n-1次排序,每次排序需进行n-i次比较,此时最坏时间复杂度为O( n 2 n^2 n2)。因此平均时间复杂度为O( n 2 n^2 n2)。
 
注: 冒泡排序可进行优化,例如记录下上一次交换的最后位置,下一次遍历终点即设置为标志位置;或者每次循环进行正反两次扫描分别确定最小值和最大值等。


2.选择排序(Selection Sort)

  选择排序是一种简单直观的排序算法。它的工作原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
 
算法描述:

  1. 从待排序的数据元素中选出最小(或最大)的一个元素,交换到序列的起始位置。
  2. 从剩余的未排序元素中寻找到最小(或最大)的元素,然后交换到已排序的序列的末尾。
  3. 重复步骤2直到待排序元素个数为零则排序完成。

选择排序
 
代码实现:

vector<int> selectionSort(vector<int>& nums)
{
   
	int len = nums.size();
	if (!len) return nums;
	for (int i = 0; i < len-1; i++)
	{
   
		int minNum = nums[i];
		int minIndex = i;
		for (int j = i + 1; j < len; j++)
		{
   
			if (nums[j] < minNum)
			{
   
				minNum = nums[j];
				minIndex = j;
			}
		}
		swap(nums[i], nums[minIndex]);
	}
	return nums;
}

 
算法分析: 表现最稳定的排序算法之一,无论什么数据进去都是O( n 2 n^2 n2)的时间复杂度,所以用到它的时候,数据规模越小越好。但优点是原理简单,并且不占用额外内存空间。


3. 插入排序(Insertion Sort)

  插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法 。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而变成一个新的、记录数增1的有序表。
 
算法描述:

  1. 将元素列第一个元素视为已排序。
  2. 从剩余的未排序元素中取出第一个元素,然后从后向前扫描已排序序列,找到合适的位置后将该元素插入。
  3. 重复步骤2直到未排序元素个数为零则排序完成

插入排序
 
代码实现:

vector<int> insertionSort(vector<int>& nums) {
   
	int len = nums.size();
	if (!len) return nums;
	for (int i = 1; i < len; i++) {
   
		int temp = nums[i];
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值