基本排序算法C++编程实现(ACM格式)

引言

本文针对常用高频排序算法的相关原理,手撕ACM格式

算法分类

比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此也称为非线性时间比较类排序
非比较类排序:不通过比较来决定元素间的相对次序,它可以突破基于比较排序的时间下界,以线性时间运行,因此也称为线性时间非比较类排序
排序算法分类
在这里插入图片描述

冒泡排序

冒泡排序原理图

void bubbleSort(vector<int> n)
{
	for (int i = 0; i < n.size(); i++)
	{
		for (int j = 0; j < n.size() - 1 - i; j++)
			if (n[j] > n[j + 1])
			{
				swap(n[j], n[j + 1]);
			}
	}
}

选择排序

选择排序原理图

void selectSort(vector<int> n)
{
	int min;
	for (int i = 0; i < n.size(); i++)
	{
		min = i;
		for (int j = i; j < n.size(); j++)
		{
			if (n[min] > n[j]) min = j;
		}
		swap(n[i],n[min]);
	}
}

插入排序

插入排序原理图

void insertSort(vector<int> nums)
{
	for (int i = 1; i < nums.size(); i++)
	{
		for (int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; j--)
		{
			swap(nums[j], nums[j + 1]);
		}
	}
}

快速排序

快速排序原理图

当需要排序的元素较多时,程序运行时间很长,因此产生了快速排序算法:

  1. 在数组中选一个基准数(通常为数组第一个)

  2. 将数组中小于基准数的数据移到基准数左边,大于基准数的移到右边

  3. 对于基准数左、右两边的数组,不断重复以上两个过程,直到每个子集只有一个元素,即为全部有序

具体实现步骤如下:

例如有一需要排序的数组为:23,45,17,11,13,89,72,26,3,17,11,13(从小到大排序):

  1. 选取数组第一个数23为基准数,存入temp变量中
  2. 定义两个指针 i 和 j,i 最开始指向数组第一个元素,j 最开始指向数组最后一个元素
  3. 指针 i 从左向右移动,指针 j 从右向左移动
  4. 先移动 j 指针,直到遇到小于等于基准数temp的数arr[j],将arr[j]填入arr[i]中
  5. 再移动 i 指针,直到遇到大于等于基准数temp的数arr[j],将arr[i]填入arr[j]中
  6. 将基准数temp赋值给arr[i]
  7. 分别将基准数左边和右边的数组按照以上方法进行聚合,直到每个子集只有一个元素,即排序完成
void quickSort(int begin, int end, vector<int>& n)
{
	if (begin < end)
	{
		int temp = n[begin];
		int L = begin;
		int R = end;
		while (L < R)
		{
			while (L < R && n[R] >= temp)
			{
				R--;
			}
			n[L] = n[R];
			while (L < R && n[L] <= temp)
			{
				L++;
			}
			n[R] = n[L];
		}
		n[L] = temp;
		quickSort(begin, L - 1, n);
		quickSort(L + 1, end, n);
	}
	else
		return;
}

整体代码

#include<iostream>
#include<vector>
using namespace std;

void bubbleSort(vector<int> n)
{
	for (int i = 0; i < n.size(); i++)
	{
		for (int j = 0; j < n.size() - 1 - i; j++)
			if (n[j] > n[j + 1])
			{
				swap(n[j], n[j + 1]);
			}
	}
	cout << "冒泡排序: ";
	for (int i = 0; i < n.size(); i++)
	{
		cout << n[i] << ' ';
		if (i == n.size() - 1) cout << endl;
	}
}

void selectSort(vector<int> n)
{
	int min;
	for (int i = 0; i < n.size(); i++)
	{
		min = i;
		for (int j = i; j < n.size(); j++)
		{
			if (n[min] > n[j]) min = j;
		}
		swap(n[i],n[min]);
	}
	cout << "选择排序: ";
	for (int i = 0; i < n.size(); i++)
	{
		cout << n[i] << ' ';
		if (i == n.size() - 1) cout << endl;
	}
}

void insertSort(vector<int> nums)
{
	for (int i = 1; i < nums.size(); i++)
	{
		for (int j = i - 1; j >= 0 && nums[j] > nums[j + 1]; j--)
		{
			swap(nums[j], nums[j + 1]);
		}
	}
	cout << "插入排序: ";
	for (int i = 0; i < nums.size(); i++)
	{ 
		cout << nums[i] << ' ';
		if (i == nums.size() - 1) cout << endl;
	}
}

void quickSort(int begin, int end, vector<int>& n)
{
	if (begin < end)
	{
		int temp = n[begin];
		int L = begin;
		int R = end;
		while (L < R)
		{
			while (L < R && n[R] >= temp)
			{
				R--;
			}
			n[L] = n[R];
			while (L < R && n[L] <= temp)
			{
				L++;
			}
			n[R] = n[L];
		}
		n[L] = temp;
		quickSort(begin, L - 1, n);
		quickSort(L + 1, end, n);
	}
	else
		return;
}

int main()
{
	vector<int> n;
	vector<int> nn;
	int num;
	while (cin >> num)
	{
		n.push_back(num);
		if (cin.get() == '\n')
			break;
	}
	nn = n;
	bubbleSort(n);//冒泡排序
	selectSort(n);//选择排序
	insertSort(n);//插入排序
	quickSort(0, n.size()-1, n);//快速排序
	cout << "快速排序: ";
	for (int i = 0; i < n.size(); i++)
	{
		cout << n[i] << ' ';
		if (i == n.size() - 1) cout << endl;
	}
	system("pause");
	return 0;
}

排序算法结果图

ACM 算法模板集 Contents 一. 常用函数与STL 二. 重要公式与定理 1. Fibonacci Number 2. Lucas Number 3. Catalan Number 4. Stirling Number(Second Kind) 5. Bell Number 6. Stirling's Approximation 7. Sum of Reciprocal Approximation 8. Young Tableau 9. 整数划分 10. 错排公式 11. 三角形内切圆半径公式 12. 三角形外接圆半径公式 13. 圆內接四边形面积公式 14. 基础数论公式 三. 大数模板,字符读入 四. 数论算法 1. Greatest Common Divisor最大公约数 2. Prime素数判断 3. Sieve Prime素数筛法 4. Module Inverse模逆元 5. Extended Euclid扩展欧几里德算法 6. Modular Linear Equation模线性方程(同余方程) 7. Chinese Remainder Theorem中国余数定理(互素于非互素) 8. Euler Function欧拉函数 9. Farey总数 9. Farey序列构造 10. Miller_Rabbin素数测试,Pollard_rho因式分解 五. 图论算法 1. 最小生成树(Kruscal算法) 2. 最小生成树(Prim算法) 3. 单源最短路径(Bellman-ford算法) 4. 单源最短路径(Dijkstra算法) 5. 全源最短路径(Folyd算法) 6. 拓扑排序 7. 网络预流和最大流 8. 网络最小费用最大流 9. 网络最大流(高度标号预流推进) 10. 最大团 11. 二分图最大匹配(匈牙利算法) 12. 带权二分图最优匹配(KM算法) 13. 强连通分量(Kosaraju算法) 14. 强连通分量(Gabow算法) 15. 无向图割边割点和双连通分量 16. 最小树形图O(N^3) 17. 最小树形图O(VE) 六. 几何算法 1. 几何模板 2. 球面上两点最短距离 3. 三点求圆心坐标 4. 三角形几个重要的点 七. 专题讨论 1. 树状数组 2. 字典树 3. 后缀树 4. 线段树 5. 并查集 6. 二叉堆 7. 逆序数(归并排序) 8. 树状DP 9. 欧拉路 10. 八数码 11. 高斯消元法 12. 字符串匹配(KMP算法) 13. 全排列,全组合 14. 二维线段树 15. 稳定婚姻匹配 16. 后缀数组 17. 左偏树 18. 标准RMQ-ST 19. 度限制最小生成树 20. 最优比率生成树(0/1分数规划) 21. 最小花费置换 22. 区间K大数 23. LCA - RMQ-ST 24. LCA – Tarjan 25. 指数型母函数 26. 指数型母函数(大数据) 27. 单词前缀树(字典树+KMP) 28. FFT(大数乘法) 29. 二分图网络最大流最小割 30. 混合图欧拉回路 31. 无源汇上下界网络流 32. 二分图最小点权覆盖 33. 带约束的轨道计数(Burnside引理) 34. 三分法求函数波峰 35. 单词计数,矩阵乘法 36. 字符串和数值hash 37. 滚动队列,前向星表示法 38. 最小点基,最小权点基
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值