常见的排序算法即排序时间长短(提升版)

排序算法

排序算法我之前总结过一篇文章,写的也挺详细的点击链接排序算法
学习了STL之后,再次学习一下排序算法,以及它们的排序一串数所需要的时间大小。

归并排序

假设初始待排序数据有n个,可以将n个数据看成n个独立的子序列,因此每个子序列的长度为1,然后两两合并,得到[n/2]个长度为2或1(注意如果n为奇数时,就会出现多出一个元素无法与其他元素合并)的有序子序列;再两两合并,一种重复下去,直到得到一个长度为n的有序序列为止,这种排序方法为2路排序方法。

动态图解

在这里插入图片描述

算法实现

合并数组 _merge
l 左边数组的首位置
mid 左边边数组的尾部位置,mid+1 右边数组的首部位置
r 右边数组的尾部

void _merge(vector<int>& vec, int l, int mid, int r){
	vector<int> tmp(vec.begin() + l, vec.begin() + r + 1);
	int lk = l;		  //左边的下标位置
	int rk = mid + 1;	  //右边数组的下标

	for (int i = l; i <= r; i++)
	{
		//左边数组下标指向end
		if (lk > mid){
			vec[i] = tmp[rk - l];
			rk++;
		}
		//右边数组下标指向end
		else if (rk > r){
			vec[i] = tmp[lk - l];
			lk++;
		}
		//判断左右两个数组的大小
		else if (tmp[lk - l] < tmp[rk - l])
		{
			vec[i] = tmp[lk - l];
			lk++;	  //左边的下标归位,右移到下一个位置
		}
		else
		{
			vec[i] = tmp[rk - l];
			rk++;	  //右边进行右移操作
		}
	}
}
void _resolve(vector<int>& vec, int l, int r){
	if (l >= r)
		return;
	int mid = (l + r) / 2;	//中间分解的下标
	_resolve(vec, l, mid);		  //递归左边的数据
	_resolve(vec, mid + 1, r);  //递归右边的数据
	//递归完了,进行合并
	_merge(vec, l, mid, r);
}
void megerSort(vector<int>& vec){
	_resolve(vec, 0, vec.size() - 1);
}

核心代码

#include <functional>
#include <ctime>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//冒泡排序
void bubbleSort(vector<int>& vec){
	for (int i = 0; i < vec.size(); i++){
		for (int j = i + 1; j < vec.size(); j++)
		{
			if (vec[i] > vec[j])
			{
				//交换两个变量
				std::swap(vec[i], vec[j]);
			}
		}
	}
}

//选择排序
void selectSort(vector<int>& vec){
	for (int i = 0; i < vec.size(); i++)
	{
		int min_nums = i;
		for (int j = i + 1; j < vec.size(); j++)
		{
			if (vec[j] < vec[min_nums])
			{
				min_nums = j;
			}
		}
		swap(vec[min_nums], vec[i]);
	}
}

//插入排序
void insertSort(vector<int>& vec){
	for (int i = 0; i < vec.size(); i++)
	{
		for (int j = i; j > 0; j--)
		{
			if (vec[j] < vec[j - 1]){
				swap(vec[j], vec[j - 1]);
			}
			else{
				break;
			}
		}
	}
}

ostream& operator<<(ostream& os, const vector<int>& vec){
	for (auto e : vec){
		cout << e << " ";
	}
	cout << endl;
	return os;
}
bool sortTest(function<void(vector<int>&)> fn){
	srand(666);	//让随机数是一致的
	vector<int> vec(10);
	for (auto& e : vec){
		e = rand() % 20;
		cout << e << " ";
	}
	cout << endl;
	fn(vec);	//通过传进来的回调函数进行排序
	cout << vec;


	vector<int> big(1000);
	for (auto& e : big){
		e = (rand() + rand());
	}
	cout << "排序:" << big.size() << "大小的数据" << endl;
	clock_t start = clock();	  //获取程序运行的时间

	fn(big);	  //测试排序时间


	clock_t end = clock();	//再次获取程序运行的时间
	cout << "排序所用时间" << (double)(end - start) / 1000 << "s" << endl;
	cout << "-------------------------------------------------" << endl;
	return true;
}
void _merge(vector<int>& vec, int l, int mid, int r){
	vector<int> tmp(vec.begin() + l, vec.begin() + r + 1);
	int lk = l;		  //左边的下标位置
	int rk = mid + 1;	  //右边数组的下标

	for (int i = l; i <= r; i++)
	{
		//左边数组下标指向end
		if (lk > mid){
			vec[i] = tmp[rk - l];
			rk++;
		}
		//右边数组下标指向end
		else if (rk > r){
			vec[i] = tmp[lk - l];
			lk++;
		}
		//判断左右两个数组的大小
		else if (tmp[lk - l] < tmp[rk - l])
		{
			vec[i] = tmp[lk - l];
			lk++;	  //左边的下标归位,右移到下一个位置
		}
		else
		{
			vec[i] = tmp[rk - l];
			rk++;	  //右边进行右移操作
		}
	}
}

//stl 库提供的排序算法
void stl_sort(vector<int>& vec){
	sort(vec.begin(), vec.end());
}
//分解数组
//l  左边的下标
//r  右边的下标
void _resolve(vector<int>& vec, int l, int r){
	if (l >= r)
		return;
	int mid = (l + r) / 2;	//中间分解的下标
	_resolve(vec, l, mid);		  //递归左边的数据
	_resolve(vec, mid + 1, r);  //递归右边的数据

	//递归完了,进行合并
	_merge(vec, l, mid, r);
}

//归并排序
void megerSort(vector<int>& vec){
	_resolve(vec, 0, vec.size() - 1);
}
int main()
{
	cout << "冒泡排序" << endl;
	sortTest(bubbleSort);	//测试冒泡排序

	cout << "选择排序" << endl;
	sortTest(selectSort);

	cout << "插入排序" << endl;
	sortTest(insertSort);

	cout << "归并排序" << endl;
	sortTest(megerSort);

	cout << "STL排序" << endl;
	sortTest(stl_sort);
	system("pause");
	return 0;
}

运行结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

尘客-追梦

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值