排序算法

基本概念

  • 时间复杂度:执行一个算法耗费的时间
  • 空间复杂度:运行一个程序需要的内存大小

输出

ostream& operator<<(ostream& os, const vector<int>& v){
  if (v.empty())
  {
	os << "[]" << endl;
	return os;
  }
  os << "[";
  for (const auto& e : v)
  {
	os << e << " ";
  }
  os << "\b]" << endl;
  return os;
}

仿函数测试

#include<functional>  // 仿函数头文件
//C++编译器没有对引用和非引用进行检查
void test(function<void(vector<int>&)> st)
{
  vector<int> vec(16);
  get_random(vec);		//获取随机数
  cout << vec;
  st(vec);				//调用传进来的排序函数
  cout << vec;
}

获取随机数

#include<random>  // 随机数头文件
void get_random(vector<int>& vec)
{
  random_device r;
  for (auto& e : vec)
  {
	e = r() % vec.size();
  }
}
在这里插入代码片

冒泡排序

#include<vector>
#include<algorithm>
using namespace std;
void bubble_sort(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])
			{
				// 交换
				int temp = vec[i];
				vec[i] = vec[j];
				vec[j] = temp;
			}
		}
	}
}

选择排序

#include<algorithm>  // swap 头文件
void select_sort(vector<int>& vec)
{
	for (int i = 0; i < vec.size(); i++)
	{
		//每次循环选出最小的值
		int min_num = i;
		for (int j = i + 1; j < vec.size(); j++)
		{
			if (vec[j] < vec[min_num])
			{
				min_num = j;
			}
		}
		swap(vec[min_num], vec[i]);
	}
}

插入排序

void insert_sort(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;	 
		}
	}
}

归并排序

// 归并数组
// left 左边数组的首部位置
// mid  右边数组的首部位置 / 左边数组的尾部位置
// right 右边数组的尾部位置
void _merge(vector<int> &vec, int left, int mid, int right)
{
	// 定义一个临时数组来复制数据
	// + 1 是因为 vector 容器左闭右开 要取到最后一个元素需要再加上 1
	vector<int> temp(vec.begin() + left, vec.begin() + right + 1);
	int leftport = left;  // 左边数组的首部位置
	int rightport = mid + 1; // 右边数组的首部位置
	for(int i = 1; i <= right; i++)
	{
		// 临时数组下标从 0 开始(相对位置) 但是实际使用的数据下标不一定从0开始 需要减去原来的起始位置
		// 左边数组的数据已经放完了 直接放右边数组的数据
		if(leftport > mid)
		{
			vec[i] = temp[rightport - left];
			rightport++;
		}
		// 右边数组的数据已经放完了 直接放左边数组的数据
		else if(rightport > right)
		{
			vec[i] = temp[leftport - left];
			leftport++;
		}
		// 从两个数组的起始位置开始排序
		else if(temp[leftport - left] < temp[rightport - left])
		{
			// 左边数组的数据比右边小 放入左边数据
			vec[i] = temp[leftport - left];  
			// 左边数组往后遍历一个数据再进行比较
			leftport++;
		}
		else
		{
			// 左边数组的数据比右边大 放入右边数据
			vec[i] = temp[rightport - left];  
			// 右边数组往后遍历一个数据再进行比较
			rightport++;
		}		
	}
}

// 分解数组
// left 左边的下标位置
// right 右边的下标位置 
void _resolve(vector<int> &vec, int left, int right)  
{
	// 递归结束条件 
	if(left >= right)
		return;
	// mid 数组下标中间值
	//int mid = (left + right) / 2; // 这这样写可能会溢出 
	int mid = (right - left) / 2 + left; //优化写法
	_resolve(vec, left, mid); // 递归分解左边数组
	_resolve(vec, mid + 1, right); // 递归分解右边数组

	// 最后进行归并
	_merge(vec, left, mid, right);
}


void mergr_sort(vector<int> &vec)
{
	// vector 容器 大小和下标的关系 
	_resolve(vec, 0, vec.size() - 1);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值