(经典实用五大排序)选择排序,计数排序,冒泡排序,快速排序,插入排序

选择排序代码段

void SelectionSort(int a[], int size)//a数组,数组长度
{
	for (int i = 0;i < size - 1;i++)//选择排序:默认按照升序,相当于首先记下第一个(以后就是第i个)下标的值i,拿第一个和第二个数组的值比较大小
		//然后第一个和第三个,第一个和第四个,直到第一个和最后一个(j<size),遍历完一遍,相当于完成一次最外面1个for循环的遍历
		//若发现前面的比后面的数值大,则记录下最小值的下标。1个内层for循环结束后,将最小的值赋给首个(第i个),将首个(第i个)的值赋给记录最小下标的那个
		// 然后拿第二个和第三个比较,第二个和第四个比较,直到最后一个。
		//数组前面是有序部分,后面是正在排序部分
	{
		int tmpMin = i;
		for (int j = i + 1;j < size;j++)
		{
			if (a[j] < a[tmpMin])//若发现前面的比后面的数值大,则记录下最小值的下标。
				tmpMin = j;
		}//1个内层for循环结束后,将最小的值赋给首个(第i个),将首个(第i个)的值赋给记录最小下标的那个
		int tmp = a[i];
		a[i] = a[tmpMin];
		a[tmpMin] = tmp;

	}
}

插入排序代码段

void InsertionSort(int a[], int size)//插入排序:,默认为升序,首先选第二个数组的值记下标为i,选第一个数组值记下标作为j,
//随着每一次j(内存for循环)增加(不能超过i),不断比较a[j]与a[i]的值,若发现(a[j] > a[i],则将从a[j]--a[i]所有的值往后挪动一位
//将a[i]的值插入到a[j]之前
{//前面是有序部分,后面是正在排序部分
	for (int i = 1;i < size;i++)
	{
		for (int j = 0;j < i;j++)
		{
			if (a[j] > a[i])//不断比较a[j]与a[i]的值
			{
				int tmp = a[i];
				for (int k = i;k > j;k--)//将从a[j]--a[i]所有的值往后挪动一位
				{
					a[k] = a[k - 1];

				}
				a[j] = tmp;//插入步骤
				break;//插入完成即终止内存for循环



			}
		}
	}
}

冒泡排序代码段

void BubbleSort(int a[], int size)
{
	for (int i = size - 1;i > 0;i--)//冒泡排序:默认升序,外层for循环是从后面逐渐向前面靠近的,靠近到0时完成排序
		//内层for循环从第一位往到i范围逐渐递增,当发现前面一位比后面一位数值大时,交换两者的值。
	{
		for (int j = 0;j < i;j++)//每次不断地把大的值往后面移动,后面就会逐渐形成递增的排序,就像冒泡一样,前面的数往后面移动
		{
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];//交换步骤
				a[j] = a[j + 1];
				a[j + 1] = tmp;

			}
		}
	}
}

计数排序(桶排序)代码段

void CountSort(int a[], int size)//计数排序,也称为桶排序,可以想象一下,搜索所有数组找出最大值,讲它作为新数组b的总(个数)长度
//size为原先需要排序数组的总(个数)长度
{
	int b[50] = { 0 };//把b所有赋值为0
	for (int i = 0;i < 50;i++)//把b所有赋值为0
	{
		b[i] = 0;
	}
	for (int i = 0;i < size;i++) //遍历一遍原先数组的个数,若出现过的原数组值,则新数组+1,出现1次+1,出现2次就+2次(可以不同位置)
	{
		b[a[i]]++;
	}
	for (int i = 0;i < 50;i++)//最后从0遍历到最大数组的值,依次输出所有数组的值
	{
		for (int j = 1;j <= b[i];j++)//出现同一个数组若有多次出现就输出多次
		{
			cout << i << endl;
		}
	}//该排序适用于数据量非常大,但数据范围并不大的情况,使用情况较少
}

快速排序(非常重要)

前面先加一个子函数

swap转换的子函数

void swap(int &a, int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

 前面先定义,在后面就可以调用


void QuickSort(int a[], int s, int e)//快速排序法:这个是非常重要的一个算法,适用于处理较多数据的值,能够极大地提高计算机运行效率,节省计算时间
//该算法运用了分支的思想
//首先 a[]为需要排序的数组,s是start的首字母,意思是需要排序数组的第一位数字,一般是0
//e是end的首字母,意思是需要排序数组的最后一位数字,若数组长度是n,一般是n-1
 
/*主要思路:先选第一个数组的值记为基准数,这个基准数的值是不会变的
	从最后一个数组j的值开始与基准数比较,倒推(j--)
	当找到比基准数小的数值时,停止比较,
	交换a[i]与a[j]的值
	从第一个数组i的值开始与基准数比较,正推(i++)
	当找到比基准数大的数值时,停止比较,
	交换a[i]与a[j]的值
	交换结束后比较i与j的值,若不相等,重新进入第一个大while循环,
	继续将j和i分别先倒退和后正推(记住先后顺序,很重要)*/
{
	if (s >= e)//这个是一个递归循环的一个出口,可以暂时不用理会,等看到后面再回头看
	{
		return;
	}
	int k = a[s];//k为基准数,是随机选取第一个数的值,是不会改变的
	int i = s, j = e;//将s和e分别赋给i和j
	while (i != j)//当i与j的值不相等时,说明排序尚未结束,重新进入循环,重新排序
	{
		while (j > i && a[j] >= k)//将j逆推过程,括号内是条件当找到比基准数小的数时,停止逆推
		{
			j--;
		}
		swap(a[i], a[j]);//交换
		while (i < j && a[i] <= k)//将i正推过程,括号内是条件当找到比基准数大的数时,停止正推
		{
			i++;
		}
		swap(a[i], a[j]);//交换
 
	}//此处跳出大的while循环,说明i和j已经是相等了,它们都跑到了中间,
	//此时,基准数就是在这个位置,基准数的左边全部是比基准数小的,基准数的右边全部是比基准数大的。
	//再把整个数组一分为二,左一半和右一半分别作为一个新的数组重新进入QuickSort函数
	//依次类推 1分2,2分4,4分8
 
 
 
	//这里使用了分治的思想,所谓大禹治水分而治之
	//就是将复杂的问题简单化,大事化小,小事化了,将整体问题局部化处理
	//这里的递归就是这样
 
	QuickSort(a, s, i - 1);//分治递归
	QuickSort(a, i + 1, e);
}
 

下面是总代码段

#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;

void swap(int &a, int &b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

void SelectionSort(int a[], int size)//a数组,数组长度
{
	for (int i = 0;i < size - 1;i++)//选择排序:默认按照升序,相当于首先记下第一个(以后就是第i个)下标的值i,拿第一个和第二个数组的值比较大小
		//然后第一个和第三个,第一个和第四个,直到第一个和最后一个(j<size),遍历完一遍,相当于完成一次最外面1个for循环的遍历
		//若发现前面的比后面的数值大,则记录下最小值的下标。1个内层for循环结束后,将最小的值赋给首个(第i个),将首个(第i个)的值赋给记录最小下标的那个
		// 然后拿第二个和第三个比较,第二个和第四个比较,直到最后一个。
		//数组前面是有序部分,后面是正在排序部分
	{
		int tmpMin = i;
		for (int j = i + 1;j < size;j++)
		{
			if (a[j] < a[tmpMin])//若发现前面的比后面的数值大,则记录下最小值的下标。
				tmpMin = j;
		}//1个内层for循环结束后,将最小的值赋给首个(第i个),将首个(第i个)的值赋给记录最小下标的那个
		int tmp = a[i];
		a[i] = a[tmpMin];
		a[tmpMin] = tmp;

	}
}

void InsertionSort(int a[], int size)//插入排序:,默认为升序,首先选第二个数组的值记下标为i,选第一个数组值记下标作为j,
//随着每一次j(内存for循环)增加(不能超过i),不断比较a[j]与a[i]的值,若发现(a[j] > a[i],则将从a[j]--a[i]所有的值往后挪动一位
//将a[i]的值插入到a[j]之前
{//前面是有序部分,后面是正在排序部分
	for (int i = 1;i < size;i++)
	{
		for (int j = 0;j < i;j++)
		{
			if (a[j] > a[i])//不断比较a[j]与a[i]的值
			{
				int tmp = a[i];
				for (int k = i;k > j;k--)//将从a[j]--a[i]所有的值往后挪动一位
				{
					a[k] = a[k - 1];

				}
				a[j] = tmp;//插入步骤
				break;//插入完成即终止内存for循环



			}
		}
	}
}

void BubbleSort(int a[], int size)
{
	for (int i = size - 1;i > 0;i--)//冒泡排序:默认升序,外层for循环是从后面逐渐向前面靠近的,靠近到0时完成排序
		//内层for循环从第一位往到i范围逐渐递增,当发现前面一位比后面一位数值大时,交换两者的值。
	{
		for (int j = 0;j < i;j++)//每次不断地把大的值往后面移动,后面就会逐渐形成递增的排序,就像冒泡一样,前面的数往后面移动
		{
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];//交换步骤
				a[j] = a[j + 1];
				a[j + 1] = tmp;

			}
		}
	}
}
void CountSort(int a[], int size)//计数排序,也称为桶排序,可以想象一下,搜索所有数组找出最大值,讲它作为新数组b的总(个数)长度
//size为原先需要排序数组的总(个数)长度
{
	int b[50] = { 0 };//把b所有赋值为0
	for (int i = 0;i < 50;i++)//把b所有赋值为0
	{
		b[i] = 0;
	}
	for (int i = 0;i < size;i++) //遍历一遍原先数组的个数,若出现过的原数组值,则新数组+1,出现1次+1,出现2次就+2次(可以不同位置)
	{
		b[a[i]]++;
	}
	for (int i = 0;i < 50;i++)//最后从0遍历到最大数组的值,依次输出所有数组的值
	{
		for (int j = 1;j <= b[i];j++)//出现同一个数组若有多次出现就输出多次
		{
			cout << i << endl;
		}
	}//该排序适用于数据量非常大,但数据范围并不大的情况,使用情况较少
}
void QuickSort(int a[], int s, int e)//快速排序法:这个是非常重要的一个算法,适用于处理较多数据的值,能够极大地提高计算机运行效率,节省计算时间
//该算法运用了分支的思想
//首先 a[]为需要排序的数组,s是start的首字母,意思是需要排序数组的第一位数字,一般是0
//e是end的首字母,意思是需要排序数组的最后一位数字,若数组长度是n,一般是n-1

/*主要思路:先选第一个数组的值记为基准数,这个基准数的值是不会变的
	从最后一个数组j的值开始与基准数比较,倒推(j--)
	当找到比基准数小的数值时,停止比较,
	交换a[i]与a[j]的值
	从第一个数组i的值开始与基准数比较,正推(i++)
	当找到比基准数大的数值时,停止比较,
	交换a[i]与a[j]的值
	交换结束后比较i与j的值,若不相等,重新进入第一个大while循环,
	继续将j和i分别先倒退和后正推(记住先后顺序,很重要)*/
{
	if (s >= e)//这个是一个递归循环的一个出口,可以暂时不用理会,等看到后面再回头看
	{
		return;
	}
	int k = a[s];//k为基准数,是随机选取第一个数的值,是不会改变的
	int i = s, j = e;//将s和e分别赋给i和j
	while (i != j)//当i与j的值不相等时,说明排序尚未结束,重新进入循环,重新排序
	{
		while (j > i && a[j] >= k)//将j逆推过程,括号内是条件当找到比基准数小的数时,停止逆推
		{
			j--;
		}
		swap(a[i], a[j]);//交换
		while (i < j && a[i] <= k)//将i正推过程,括号内是条件当找到比基准数大的数时,停止正推
		{
			i++;
		}
		swap(a[i], a[j]);//交换

	}//此处跳出大的while循环,说明i和j已经是相等了,它们都跑到了中间,
	//此时,基准数就是在这个位置,基准数的左边全部是比基准数小的,基准数的右边全部是比基准数大的。
	//再把整个数组一分为二,左一半和右一半分别作为一个新的数组重新进入QuickSort函数
	//依次类推 1分2,2分4,4分8



	//这里使用了分治的思想,所谓大禹治水分而治之
	//就是将复杂的问题简单化,大事化小,小事化了,将整体问题局部化处理
	//这里的递归就是这样

	QuickSort(a, s, i - 1);//分治递归
	QuickSort(a, i + 1, e);
}




int main()
{
	int a[10] = { 9,8,7,6,5,10,11,28,33,1 };
	//SelectionSort(a,10);
	//InsertionSort(a,10);
	//BubbleSort(a, 10);
	//CountSort(a,10);
	//RadixSort(a,10);
	QuickSort(a,0,9);
	for (int i = 0;i < 10;i++)
	{
		cout << a[i] << endl;
	}
	return 0;
}

以上的代码,借鉴了学长讲课时的代码,并且我做了注释笔记,下面视频是学长讲课的视频,在b站,本次引用并不用作任何商业用途,仅做学习交流使用,如有冒犯侵权行为,请联系文章作者进行修改,谢谢。

第一讲课排序算法c++_哔哩哔哩_bilibili

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值