基本排序算法-C++

8 篇文章 0 订阅
本文详细介绍了三种比较类排序算法:冒泡排序通过两两比较交换实现排序,时间复杂度为O(n^2);快速排序采用分治思想,平均时间复杂度为O(nlogn);选择排序则是在每轮中找到最小值与无序区交换,时间复杂度同样为O(n^2)。文章提供了每种排序的代码实现和算法思路。
摘要由CSDN通过智能技术生成

目录

比较类排序

1交换排序

1.1冒泡排序

1.2快速排序

2选择排序

2.1简单选择排序

2.2堆排序


比较类排序

1交换排序

1.1冒泡排序

算法思路:对于n个无序数,进行n次排序,每一次都是两两比较,进行交换,将大的数往后面放,这样每一次比较下来就能将当前比较的数字中最大的找出来。第一次是所有数字例如10个,第二次就是除最大数外的9个,以此类推。理解了这个算法思路,代码也就非常容易了。

code:

void bubbleSort(int* arr, int len)
{
	if (len <= 1)
	{
		cout << "数组为空或无需排序";
		return;
	}
	// 需要整体排序的次数
	for (int i = 0; i < len - 1; i++)
	{
		// 对每次需要排序的数字进行两两比较,大的往后面放
		for (int j = 0; j < len - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j + 1];
				arr[j + 1] = arr[j];
				arr[j] = temp;
			}
		}
		// 内循环每次结束,都会产生一个最大值在最后的位置
	}
}

算法时间复杂度 :O(n^2)

动画演示:

在这里插入图片描述

1.2快速排序

算法思路:快速排序采用了分块处理或叫分治的思想,选取一个中心点,将剩下的数字比中心点大的放在右边,比中心点小的放在左边,以此形成两个子序列,继续如此,直到子序列中元素只剩一个。即:对于一个无序数列,存在一个左光标、右光标及一个中心点。默认选取第一个元素为中心点,然后从右边开始移动右光标,将光标指向的数字与中心点进行比较,如果比中心点大,则光标继续移动,如果比中心点小,则将当前数放在左光标处。接着开始移动左光标,如果光标所在数比中心点小,则继续移动,如果比中心点大,则将其移动到右光标位置。下来移动右光标,反复如此,当做右光标重合时,将中心点放在光标处。对于此时产生的两个子序列,继续及逆行上述操作,直到每个子序列中只有一个元素为止。

code:

void quitSort(int* arr, int left, int right)
{
	// 递归退出条件
	if (left >= right)
	{
		return;
	}
	int L = left;
	int R = right;
	int pivot = arr[L];
	while (L < R)
	{
		// 等待移动右索引
		while (L < R && arr[R] >= pivot)
		{
			R--;
		}
		// 将小于中心点的移动到左光标处
		if (L < R)
		{
			arr[L] = arr[R];
		}	
		// 等待移动左索引
		while (L<R && arr[L]<=pivot)
		{
			L++;
		}
		// 将大于中心点的移动到右光标处
		if (L < R)
		{
			arr[R] = arr[L];
		}
		
		// 将中心点移动到光标重合处
		if (L >= R)
		{
			arr[L] = pivot;
		}
	}
	// 递归左右子组
	quitSort(arr, left, R-1);
	quitSort(arr, R + 1, right);
}

算法时间复杂度 :O(nlogn)~ O(n^2) 

动画演示:在这里插入图片描述

2选择排序

2.1简单选择排序

 算法思路:选择排序的基本思路是针对n个数(分为有序和无序部分,初始时有序序列为空,全部是无序序列),需要进行n-1次排序,每次排序都能找出当前无序序列中的最小值,将其与原有序序列后一个位置的属于无序序列的值进行交换,这样下来进行n-1次即可对数据及进行排序。这里代码有两种方式,即每次无序序列找到最小值之后就进行交换或者无序序列找到当前最小值之后就进行交换,前者交换次数少,如截图所示。

code:

/*选择排序-每轮交换一次(利用中间变量)*/
void selectSort(int* arr, int len)
{
	int count = 0;
	// 针对每一个书进行比较
	for (int i = 0; i < len; i++)
	{
		// 初始时最小设为第一个数
		int small = arr[i];
		// 初始时最小数索引设为第一个数
		int smallIndx = i;
		// 每一个数和剩下的数比较
		for (int j = i + 1; j < len; j++)
		{
			// 如果比第一个数小,则最小的数放在左边序列中的最后
			if (small > arr[j]) 
			{
				count++;
				small = arr[j];
				smallIndx = j;
			}
		}

		// 与无序区第一个进行交换
		int temp = arr[i];
		arr[i] = small;
		arr[smallIndx] = temp;
	}
	cout << "交换了:" << count << "次" << endl;
}

/*选择排序-每轮交换多次*/
void selectSort2(int* arr, int len)
{
	int count = 0;
	// 针对每一个书进行比较
	for (int i = 0; i < len; i++)
	{
		// 每一个数和剩下的数比较
		for (int j = i + 1; j < len; j++)
		{
			// 如果比第一个数小,则最小的数放在左边序列中的最后
			if (arr[i] > arr[j])
			{
				count++;			
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;	
			}
		}
	}
	cout << "交换了:" << count << "次" << endl;
}

截图:

算法时间复杂度:O(n^2)

动画演示:

在这里插入图片描述

2.2堆排序

待更新

声明:本文中的动画示意引自,侵删:10大常用的排序算法(算法分析+动图演示)_Five-菜鸟级的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我啥都会

如果觉得对您有帮助,打赏一下吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值