[数据结构]---排序总结(简单代码实现 简单图解 总结)

本文详细介绍了8种排序算法,包括插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序以及计数排序。每种算法都阐述了其基本思想、时间复杂度、空间复杂度和稳定性,并提供了简单的代码实现和图解说明。特别地,计数排序是一种非比较型整数排序算法,适用于特定场景。
摘要由CSDN通过智能技术生成

目录

排序算法常见的有(7+1)种:

下面先介绍前七种:

算法一:插入排序(插入排序是一种简单直观的排序方法.)

算法二:希尔排序(缩小增量排序)

算法三:选择排序

算法四:堆排序

算法五:冒泡排序 

算法六:快速排序 

算法七:归并排序

还要介绍一种特殊的排序方法-->计数排序

算法八:计数排序

排序算法复杂度及稳定性分析:


排序算法常见的有(7+1)种:

下面先介绍前七种:

 

算法一:插入排序(插入排序是一种简单直观的排序方法.)

算法思想:每次将一个需要排序的数据插入到已经排好序的有序数据序列中,从而得到一个新的、个数加一的有序数据序列.

插入排序的基本操作:

  1. 将待排序序列中第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
  2. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面)。

代码实现:

void InsertSort(int* a, int n)
{
	assert(a);
	for (int i = 1; i < n; ++i)
	{
		//单个元素排序  第一个元素不需要排序
		//找到已经排好序的最后一个元素的位置
		int end = i-1;
		//把end+1位置元素插入到合适的位置
		int tmp = a[i];
		while (end>=0 && a[end]>tmp)
		{
			a[end + 1] = a[end];
			--end;
		}
		//找到合适的位置放
		a[end + 1] = tmp;
	}
}
int main()
{
	int a[] = { 2, 5, 1, 3, 6, 8, 9,122, 4, 7 };
	PrintArray(a, 10);
	InsertSort(a, 10);
	PrintArray(a, 10);
	return 0;
}

简单过程图解说明:

小结:

  1. 时间复杂度 :O(N^2)
  2. 空间复杂度 :O(1)
  3. 稳定性        :稳定
  4. 适合场景     :接近有序序列,时间复杂度趋近于O(N)--> 对于有序序列,时间复杂度O(N) 

 

算法二:希尔排序(缩小增量排序)

希尔排序是插入排序的一种又称“缩小增量排序”,是对直接插入排序算法的一种更高效的改进优化版本。

算法思想(过程):先取一个小于n的整数gap1作为第一个增量,把文件的全部记录分组。所有距离为gap的1倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量gap2<gap1重复上述的分组和排序,直至所取的增量gap =1,即所有记录放在同一组中进行直接插入排序为止。

代码实现:

void ShellSort(int* a, int n)
{
	//gap>1 预排序
	//gap=1 最终排序过程
	int gap=n;
	while (gap>1)
	{
		gap = gap / 3 + 1;  //+1是保证最后一次gap为1插入排序
		for (int i = gap; i<n; i++)
		{
			int end = i-gap;
			int tmp = a[i];
			while (end >= 0 && a[end]>tmp)
			{
				a[end + gap] = a[end];
				end -= gap;
			}
			a[end + gap] = tmp;
		}
	}
}
int main()
{
	int a[] = { 2, 5, 1, 3, 6, 8, 9, 122, 4, 7 };
	PrintArray(a, 10);
	ShellSort(a, 10);
	PrintArray(a, 10);
	return 0;
}

简单过程图解说明:

小结:

  1. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序
  2. 时间复杂度 :平均:O(1.3)--O(N^2)
  3. 空间复杂度 :O(1)
  4. 稳定性:    不稳定

 

算法三:选择排序

基本思想:每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的
数据元素排完 。

基本操作:

  1. 第一次从待排序的数据序列中选出最小(或最大)的一个数据,存放在序列的起始位置,
  2. 然后再从剩余的未排序数据序列中寻找到最小(大)数据,然后放到已排序的序列的末尾。
  3. 以此类推,直到全部待排序的数据的个数为零

代码实现(包含普通写法和优化写法):

//基本写法
//void SelectSort1(int* a, int n)
//{
//	int max = 0;
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < n;i++)
//	{
//		max = a[0];
//		for (j = 1; j < n - 1;j++)
//		{
//			if (a[j]>a[max])
//			{
//				max = j;
//			}
//		}
//		if (max!=j-1)
//		{
//			Swap(&a[j - 1], &a[max]);
//		}
//	}
//
//}

//优化写法
void SelectSort2(int* a, int n)
{
	
	int begain = 0;
	int end = n - 1;
	while (begain<end)
	{
		//每一次选一个最大的和最小的,放在相应的位置
		int i;
		int max;
		int min;
		max = min = begain;
		for (i = begain; i <= end;i++)
		{
			if (a[i]<a[min])
				min = i;
			if (a[i]&
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值