几种经典排序算法的演示(C++实现)

2023-11-13

该文章所有代码均基于SortView类,头文件及基本代码如下

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

class SortView {
public:
	void BubbleSort();//冒泡排序
	void SelectionSort();//选择排序
	void InsertionSort();//插入排序
	void ShellSort();//希尔排序
	void Quicksort(int low, int high);//快速排序
	void MergeSort(int left, int right);//归并排序
	void Merge(int left, int right,int mid);//归并排序
	void RadixSort();//基数排序
	void Init(int n);//初始化数组
	void Show();//打印数组
	int Size();
private:
	vector<int> Unsort;
	int temp[];
};

void SortView::Init(int n) {
	for (int i = 0; i < n; i++) {
		Unsort.push_back(rand());
	}
}

void SortView::Show() {
	for (int i = 0; i < Unsort.size(); i++) {
		cout << Unsort[i] <<" ";
	}
	cout << endl;
}

int SortView::Size() {
	return Unsort.size();
}

1、冒泡排序(BubbleSort)

冒泡排序是一种较为简单的排序算法,其基本思想就是循环遍历需要排序的元素,依次比较两个相邻的元素,如果它们之间的顺序不符合需要的顺序,即将他们进行交换,知道某一次循环遍历没有需要交换的元素,排序完成。

void SortView::BubbleSort() {
	int n = Unsort.size()-1;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n-i; j++) {
			if (Unsort[j] > Unsort[j + 1]) {
				swap(Unsort[j], Unsort[j + 1]);
			}
		}
	}
	return;
}

2、快速排序(Quicksort)

相对于冒泡排序来说,快速排序要比其快将近一倍的时间,具体实现的基本思想就是找一个基准元素(我选取的基准元素每次都是第一个元素)然后将基准元素和后面的元素进行比较,将所有比基准元素小的放到基准元素的左边,所有比基准元素大的放到基准元素的右边,递归进行调用自身,完成左右两边,就完成了排序。

void SortView::Quicksort(int low,int high) {
	int UNhigh = high;
	int corrent = low;//该变量记录当前基准元素
	if (low > high)return;
	for (high; high > 0; high--) {
		if (Unsort[high] < Unsort[corrent]) {
			for (low; low < high; low++) {
				if (Unsort[low] > Unsort[high]) {
					swap(Unsort[low], Unsort[high]);
					break;
				}
			}
		}
		if (high == low) {
			break;
		}
	}
	swap(Unsort[corrent], Unsort[high]);
	Quicksort(low, high-1);
	Quicksort(high + 1, UNhigh);
}

3、归并排序(MergeSort)

归并排序采用了分而治之的思想,将很长的一段数字序列排序,分成很多的短序列进行排序,当然,分到数组里面只有一个元素的时候,该段序列本来就是有序的,对这子序列分别采用归并排序,将排序好的子序列合并成一个最终的排序序列,即完成了排序。归并排序是稳定排序,它也是一种十分高效的排序,能利用完全二叉树特性的排序一般性能都不会太差。

void SortView::MergeSort(int left,int right) {
	if (left < right) {
		int mid = (left + right) / 2;
		MergeSort(left, mid);//左边归并排序,使得左子序列有序
		MergeSort(mid + 1, right);//右边归并排序,使得右子序列有序
		Merge(left, right, mid);
	}
}

void SortView::Merge(int left, int right, int mid) {
	int i = left;
	int j = mid + 1;
	int t = 0;
	while (i <= mid && j <= right) {//将子序列按顺序放入临时序列中
		if (Unsort[i] <= Unsort[j]) {
			temp[t++] = Unsort[i++];
		}
		else {
			temp[t++] = Unsort[j++];
		}
	}
	while (i <= mid) {//剩余的左序列
		temp[t++] = Unsort[i++];
	}
	while (j <= right) {//剩余的右序列
		temp[t++] = Unsort[j++];
	}
	t = 0;
	while (left <= right) {//将临时序列放入原序列
		Unsort[left++] = temp[t++];
	}
}

4、选择排序(SelectionSort)

选择排序的实现较为简单,基本原理就是拿未排序的元素序列的首元素和后面序列的元素逐个比较,找出最小的与其进行位置调换当遍历完全部序列后,排序也就完成了。

void SortView::SelectionSort(){
	int min;
	int n = Unsort.size();
	for (int i = 0; i < n; i++) {
		min = i;
		for (int j = i + 1; j < n; j++) {
			if (Unsort[i] > Unsort[j]) {
				if (Unsort[min] > Unsort[j])min = j;
			}
		}
		swap(Unsort[min], Unsort[i]);
	}
}

5、插入排序(InsertionSort)

插入排序的基本思想就是从前往后遍历数组,拿到当前位置的值后,与前一个元素进行比较,如果比前面的值小,则进行替换,循环执行,直到有元素比当前元素大,或者遍历到序列的头。当遍历完整个值序列,则全部值排序完毕。

void SortView::InsertionSort() {
	int n = Unsort.size();
	for (int i = 0; i < n; i++) {
		for (int j = i; j > 0; j--) {
			if (Unsort[j] < Unsort[j-1]) {
				swap(Unsort[j], Unsort[j-1]);
			}
			else if (Unsort[j] > Unsort[j-1])break;
			
		}
	}
}

6、希尔排序(ShellSort)

希尔排序结合了插入排序的思想,在插入排序的思想下将比较的间距调整为了一个固定的值 (increment/3+1)在这个值还大于一的时候,循环进行插入排序,当这个值小于或者等于一了,排序完毕。

void SortView::ShellSort() {
	int end = Unsort.size()-1, start = 0;
	int increment = Unsort.size();//所有元素的数量
	int temp{ 0 };
	while (increment > 1) {
		increment = increment / 3 + 1;
		for (int i = start + increment; i <= end; ++i) {    //对每个划分进行直接插入排序
			if (Unsort[i - increment] > Unsort[i]) {
				temp = Unsort[i];
				int j = i - increment;
				while (j >= start && Unsort[j] > temp)
				{    //移动元素并寻找位置
					Unsort[j + increment] = Unsort[j];
					j -= increment;
				}
				Unsort[j + increment] = temp;
			}
		}
	}
}

7、基数排序(RadixSort)

基数排序结合了计数排序的思想,先找到整个序列中最大的数字,拿到最高阶次,然后将整数按阶次切割成不同的数字,然后按每个阶次分别比较。具体实现是:将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从个位开始,依次进行一次排序。这样从个位排序一直到最高阶次排序完成以后, 待排序序列就变成一个有序序列,排序完成。

void SortView::RadixSort() {
	auto max = max_element(Unsort.begin(), Unsort.end());
	int exp, n = Unsort.size();
	for (exp = 1; *max / exp > 0; exp *= 10) {
		int i, buckets[10] = { 0 };
		for (i = 0; i < n; i++)
			buckets[(Unsort[i] / exp) % 10]++;
		for (i = 1; i < 10; i++)
			buckets[i] += buckets[i - 1];
		for (i = n - 1; i >= 0; i--)
		{
			temp[buckets[(Unsort[i] / exp) % 10] - 1] = Unsort[i];//把元素放到应该在的位置
			buckets[(Unsort[i] / exp) % 10]--;
		}
		for (i = 0; i < n; i++)
			Unsort[i] = temp[i];
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

几种经典排序算法的演示(C++实现) 的相关文章

  • 关于蓝桥杯的乱七八糟的话(经验、心得、建议、技巧)

    参赛经验 心得 先介绍一下自身情况 我参加的是C C B组 所在的赛区是江苏赛区 参加过三次蓝桥杯 最好的成绩是国三 没错我就是个小辣鸡 蓝桥杯省赛题目一般有结果填空 代码填空和程序题三种题型 但是第十届已经没有了代码填空 填空题只要结果
  • leaftlet 中Polygon的使用属性

    绘制一个面 var latlngs 37 109 05 41 109 03 41 102 05 37 102 04 var polygon L polygon latlngs color red addTo map map fitBound
  • videopose3d制作自己的视频转换

    videopose3d制作自己的视频转换 最近学了深度学习 对其中的人体姿态检测和识别感兴趣 但是网上包括官方网站的都是对源码的解读 没有一个是利用自己的视频进行姿态检测和渲染的 因此自己试着按照官方的in the wild教程试了一下 很
  • Python开发图形可视化界面程序(一)

    前言 近来使用Python开发了一些简单的辅助脚本 发现这真的是一门很有趣的语言 于是乎 便想着使用python来开发一些具有图形可视化界面 GUI 的程序 对于python来说 支持其开发GUI可视化程序的框架非常之多 简直让人眼花燎原
  • bugfree pdo mysql扩展模块_windows平台bugfree3.0.3搭建心得(nginx+php+mysql+bugfree+RunHiddenConsole)...

    之前没做过windows服务器管理 我的认识还停在个人用户操作系统的认知上 这次搭建bugfree环境 挺多麻烦的 在安装之前 我百度的bugfree搭建大多是使用xampp集成环境的安装方法 然后我就照做 下载xampp 然后安装到系统c
  • C语言实现两数相加的三种方法

    笔试题里面看到的 总结一下 分享给需要的小伙伴 一 原始办法 这种方法最直观明了 int add int x int y return x y 二 利用printf的返回值 这个操作鲜为人知 include
  • linux域名解析

    linux域名解析 首先确保你的电脑可以连上网 服务端和客户端能够连通 1 本地解析 优先级高 在服务端中 ping www baidu com 找出ip 在客户端中的浏览器中搜索ip地址就可以上网 但是ip地址记起来非常不方便 所以这里用
  • 网贷风控体系之-风控模型

    网贷风控体系之 风控模型 大数据风控模型主要分为两类 反欺诈模型 交叉验证 聚类分析 黑灰名单 二元好坏模型 准入阶段 授信额度期限利率模型 评分卡模型 LR XGBoost 贷中阶段 风险变化评估 风险预警 贷后阶段 催收时机 催收方法
  • TVM:源码编译安装

    TVM Linux源码编译安装 笔者环境 OS Ubuntu 18 04 CMake 3 10 2 gcc 7 5 0 cuda 11 1 编译安装过程总览 本文将简介 tvm 的编译安装过程 包含两个步骤 通过C 代码构建共享库 设置相关
  • Android - BlueTooth BLE 之 Central 与 Peripheral

    一 前言 Andorid 5 0 之前是无法进行 外围设备开发的 在Android 5 0 API 21 android bluetooth le包下 新增加 Scaner相关类和 Advertiser 相关类 目前最后使用Scanner相
  • 49天精通Java,第5天,Java控制台输入输出语句

    目录 一 控制台输出 二 读取输入 三 格式化输出 1 类型转换字符 2 代码实例
  • 搭建github服务器_【教程篇】使用GitHub+Hexo搭建个人静态博客

    嗨 大家好 你们的万金油管家小e又来了 这次就教大家一些利用GitHub和Hexo本地服务器搭建个人博客的教程 可能教程要好几期 那么这期就先从最最基础的GitHub的注册 以及本地环境的搭建 GitHub仓库的建立等等开始 近年来很多人都
  • 十大应用安全威胁

    常见应用安全威胁 OWASP TOP 10 2013 注入 失效的身份认证和会话管理 跨站脚本攻击 XSS 不安全的直接对象引用 安全配置错误 敏感信息泄露 功能级访问控制缺失 跨站请求伪造 CSRF 使用含有已知漏洞的组件 未验证的重定向
  • 【MyBatis】MyBatis 二级缓存全详解

    1 概述 转载 MyBatis 二级缓存全详解 上一篇文章中我们介绍到了 MyBatis 一级缓存其实就是 SqlSession 级别的缓存 什么是 SqlSession 级别的缓存呢 一级缓存的本质是什么呢 以及一级缓存失效的原因 我希望

随机推荐

  • Ubuntu扩展存储合理分配swap分区

    文章目录 前言 1 为Ubuntu扩存 外部存储 1 1修改存储 1 2 初始化分配的磁盘 2 为Ubuntu调整swap分区大小 总结 前言 我们在Ubuntu上运行某些大型游戏或者编译一些工程代码的时候 往往会遇到内存或外部存储不够导致
  • mac 本地运行 http-proxy-middleware ,请求超时

    const http require http customer target http 10 10 111 192 8080 target http user jinfu baohan com changeOrigin true 是否启用
  • JS如何将变量作为一个对象的Key

    JS如何将变量作为一个对象的Key var lastWord last word var a first word hello lastWord world a first word hello a lastWord world a las
  • Mysql进阶优化篇06——分组查询优化、分页查询优化、覆盖索引

    前 言 作者简介 半旧518 长跑型选手 立志坚持写10年博客 专注于java后端 专栏简介 mysql基础 进阶 主要讲解mysql数据库sql刷题 进阶知识 包括索引 数据库调优 分库分表等 文章简介 本文将介绍JOIN语句的底层原理
  • Java中通过反射+自定义注解判断对象中部分属性是否为空,返回为空字段的名称或自定义含义

    场景 若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出 若依管理系统前后端分离版基于ElementUI和SpringBoot怎样实现Excel导入和导出 霸道流氓气质的博客 CSDN博客 在上
  • 【爬虫】python复原网站前端密码加密

    爬虫 python复原网站前端密码加密 前言 前几天学完了尚硅谷的爬虫课程 这几天刚好有一门课出成绩了 我们学校的教务处的查分系统手机无法正常打开 好像只有ios设备用不了 学校的一些学长弄了一个公众号 在公众号里面手机可以很方便的查到分数
  • SMTP服务器地址及端口

    在开发过程中有些场景会用到发送邮件的功能 根据客户需求不同会使用到各种类型的邮箱服务 发送邮件的方法都大同小异 差异大的就是各个邮箱服务的地址及端口 找起来比较麻烦 整理到部分比较常用的可根据需要获取 部分自建的邮箱的SMTP是自定义的 需
  • ARP协议和攻击原理

    转自 https blog 51cto com 13570193 2083332 ARP 在TCP IP协议栈中 最不安全的协议莫过于ARP了 我们经常听到的网络扫描 内网渗透 流量欺骗等等 他们基本上都与ARP有关系 甚至可以说 他们的底
  • 我的ACM生涯——迷失

    自从EC打铁归来已经一星期了了 这一周我都在颓废 似乎又回到以前的自己 没想到 我在集训队呆了2年 还是菜的真实 虽然把所有的原因 都归结到菜上 的确是个逃避问题正解的办法 我决定写点什么总结 算是一个收尾 先来做个回忆 还记得第一次看到自
  • SpringBoot 事件发布监听机制使用、分析、注意点 (一篇到位)

    前言 这一篇从应用角度来跟大伙讲讲 这个 spring 事件监听机制 顺便涉及到那些我认为大家应该一块了解的 我也会展开说说 文章内容 包括不限于 1 对比观察者模式 2 应用场景的分析 3 事件的创建 编码介绍 4 事件如何 发出 5 事
  • ES6:迭代器 Iterator

    迭代器是一个统一的接口 也可以叫遍历器 它的作用是使各种数据结构可被便捷的访问 它是通过一个键为Symbol iterator 的方法来实现 定义一个数组 const people Tom Jerry Mario Yoshi 在控制台打印它
  • 【JavaScript】找出字符串中出现最多的字符及次数

    统计字符串中各个字符的长度 var str dafadfdaaaaaaaaafffffcccccccssssssss var obj for var i 0 i
  • Unity屏幕适配解决方案

    文章目录 UI尺寸选择 市面设备比例 内存占用 分辨率适配 高分辨率 分屏模式 宽高比适配 常规尺寸适配 刘海屏适配 全面屏适配 UI尺寸选择 市面设备比例 截至2017年9月 iOS与Android移动游戏设备比例约为iOS占28 And
  • 1827. 最少操作使数组递增 ----- 贪心算法

    给你一个整数数组 nums 下标从 0 开始 每一次操作中 你可以选择数组中一个元素 并将它增加 1 比方说 如果 nums 1 2 3 你可以选择增加 nums 1 得到 nums 1 3 3 请你返回使 nums 严格递增 的 最少 操
  • 汇编语言编程,将DATAS段中的每个单词的前4个字母改为大写并将改写后的结果分4行输出到屏幕上

    编程 将DATAS段中的每个单词的前4个字母改为大写并将改写后的结果分4行输出到屏幕上 题目 编程 将DATAS段中的每个单词的前4个字母改为大写并将改写后的结果分4行输出到屏幕上 DATAS SEGMENT db 1 display db
  • 01-Java语言基础

    01 01 计算机基础知识 计算机概述 了解 A 什么是计算机 计算机在生活中的应用举例 计算机 Computer 全称 电子计算机 俗称电脑 是一种能够按照程序运行 自动 高速处理海量数据的现代化智能电子设备 由硬件和软件所组成 没有安装
  • Linux网络编程:libevent事件通知I/O框架

    文章目录 一 libevent库 二 libevent框架 1 常规事件event 1 1 创建事件event event new 1 2 添加事件到 event base event add 1 3 从event base上摘下事件 ev
  • cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function ‘cvtColor‘> Overload resolution

    不知道有没有小伙伴遇到了和我一样的报错 查找相关解决办法 大多的回答是让我降opencv版本 降版本过程中遇到问题 无法找到相关版本 可能是python版本的问题 最后经过不断尝试搜索解决问题 发现只是自己的函数用法写错了 有相同错误的小伙
  • 精通python100天——第二天:python基础

    1 熟悉交互式环境 python交互式环境虽然不像IDE在开发中天天要用到 但它也是我们入门不可忽视的一个环节 那怎么进入python交互式环境呢 分两种情况 第一种 安装了annocoda 点击Windows桌面左下角徽标 找到Anaco
  • 几种经典排序算法的演示(C++实现)

    该文章所有代码均基于SortView类 头文件及基本代码如下 include