当前位置: 首页 > news >正文

C++快排 ~ 三种实现方法

C++快排 ~ 三种实现方法

  • 1、前言
  • 2、代码
    • 2.1 hoare 版本
      • 2.1.1 代码
      • 2.1.2 运行结果
    • 2.2 挖坑法
      • 2.2.1 代码
      • 2.2.2 运行结果
    • 2.3 前后指针
      • 2.3.1 代码
      • 2.3.2 运行结果

1、前言

快排的理论部分,有兴趣者可点击博客 温故而知新 -> 数据结构 ->排序 或通过其他方式进行理解!
博主其实之前实现过快排,具体可见博客 温故而知新 -> 数据结构 ->排序 ->程序实现2_利用C++ 中的内容,但因为当时实现是函数之间的层层调用,虽然理解不难,但代码量会比较多,也有点麻烦,所以在本篇博客中将对其进行精简!

快排中,将区间按照基准值划分为左右两半部分的常见方式有:

  1. hoare版本
  2. 挖坑法
  3. 前后指针版本

所以下面的程序实现将按这三种方法进行说明!

2、代码

2.1 hoare 版本

2.1.1 代码

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

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort(vector<int>& arr, int left, int right) // hoare  升序
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	int start = left;
	while (begin < end)
	{
		while (begin < end && arr[end] >= key)
			--end;
		while (begin < end && arr[begin] <= key)
			++begin;
		if (begin != end)//此句是用于减少不必要的操作,可加可不加
			swap(arr[begin], arr[end]);
	}
	swap(arr[start], arr[begin]);
	quickSort(arr, left, begin - 1);//此处begin与end可任选其一
	quickSort(arr, begin + 1, right);
}
// 将数组以降序进行排列!
void quickSort_2(vector<int>& arr, int left, int right) // hoare  降序
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	int start = left;
	while (begin < end)
	{
		while (begin < end && arr[end] <= key)
			--end;
		while (begin < end && arr[begin] >= key)
			++begin;
		if (begin != end)//此句可加可不加
			swap(arr[begin], arr[end]);
	}
	swap(arr[start], arr[begin]);
	quickSort_2(arr, left, begin - 1);//此处begin与end可任选其一,因为上面的循环结束后,begin会与end相等
	quickSort_2(arr, begin + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

注意:上述升序与降序的主要区别就是程序中的大小判断条件相反!

2.1.2 运行结果

在这里插入图片描述

2.2 挖坑法

2.2.1 代码

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

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort2(vector<int>& arr, int left, int right) 
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	while (begin < end)
	{
		while (begin < end && arr[end] >= key)
			--end;
		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
		while (begin < end && arr[begin] <= key)
			++begin;
		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
	}
	arr[begin] = key;
	quickSort2(arr, left, end - 1);
	quickSort2(arr, end + 1, right);
}
// 将数组以降序进行排列!
void quickSort2_2(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int key = arr[left];
	int begin = left;
	int end = right;
	while (begin < end)
	{
		while (begin < end && arr[end] <= key)
			--end;
		arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
		while (begin < end && arr[begin] >= key)
			++begin;
		arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
	}
	arr[begin] = key;
	quickSort2_2(arr, left, begin - 1);
	quickSort2_2(arr, begin + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort2(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort2_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

2.2.2 运行结果

在这里插入图片描述

2.3 前后指针

2.3.1 代码

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

void display(vector<int>& arr)
{
	for (auto& n : arr)
		cout << n << " ";
	cout << endl;
}
// 将数组以升序进行排列!
void quickSort3(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int prev = left;
	int cur = left + 1;
	int key = arr[left];
	while (cur <= right)
	{
		if (arr[cur] < key && ++prev != cur)//小于基准值且不连续时进行交换
			swap(arr[prev], arr[cur]);
		++cur;
	}
	swap(arr[left], arr[prev]);
	quickSort3(arr, left, prev - 1);
	quickSort3(arr, prev + 1, right);
}
// 将数组以降序进行排列!
void quickSort3_2(vector<int>& arr, int left, int right)
{
	if (left >= right)
		return;
	int prev = left;
	int cur = left + 1;
	int key = arr[left];
	while (cur <= right)
	{
		if (arr[cur] > key && ++prev != cur)//小于基准值且不连续时进行交换
			swap(arr[prev], arr[cur]);
		++cur;
	}
	swap(arr[left], arr[prev]);
	quickSort3_2(arr, left, prev - 1);
	quickSort3_2(arr, prev + 1, right);
}
void test()
{
	vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
	cout << "原数组:"; display(arr);
	quickSort3(arr, 0, arr.size() - 1);
	cout << "升序排列:"; display(arr);
	quickSort3_2(arr, 0, arr.size() - 1);
	cout << "降序排列:"; display(arr);
}

int main()
{
	test();
	return 0;
}

2.3.2 运行结果

在这里插入图片描述
上述三种方法,个人推荐用第二种~

相关文章:

  • JavaEE开发之SpringMVC框架整合1
  • 写作一笔记
  • 【React的特性事件表单的使用函数组件】
  • OS--学习笔记:操作系统概述
  • C#进阶07——反射和特性
  • WebRTC研究:audio 丢包判断
  • Nginx-HTTPS 配置
  • 2022-09-07 mysql/stonedb-多线程遍历元组问题分析
  • 单调栈题目:找出最具竞争力的子序列
  • Python运算符,数字,字符串
  • JSP教学评估管理系统myeclipse开发mysql数据库bs框架java编程web网页结构
  • 【vue3】04. 跟着官网学习vue3
  • xv6源码阅读——xv6的启动,进程初识
  • 金仓数据库KingbaseES客户端应用参考手册--13. sys_isready
  • 前端工程师面试题总结
  • [iOS]Core Data浅析一 -- 启用Core Data
  • __proto__ 和 prototype的关系
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 【翻译】babel对TC39装饰器草案的实现
  • CSS中外联样式表代表的含义
  • Vue.js-Day01
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 关于Java中分层中遇到的一些问题
  • 官方新出的 Kotlin 扩展库 KTX,到底帮你干了什么?
  • 计算机在识别图像时“看到”了什么?
  • 聊聊flink的TableFactory
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 如何胜任知名企业的商业数据分析师?
  • 实现菜单下拉伸展折叠效果demo
  • 系统认识JavaScript正则表达式
  • 从如何停掉 Promise 链说起
  • 交换综合实验一
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #14vue3生成表单并跳转到外部地址的方式
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (12)目标检测_SSD基于pytorch搭建代码
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (附源码)spring boot基于小程序酒店疫情系统 毕业设计 091931
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (七)Knockout 创建自定义绑定
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)大型网站的系统架构
  • (转)视频码率,帧率和分辨率的联系与区别
  • ******IT公司面试题汇总+优秀技术博客汇总
  • ./configure,make,make install的作用(转)
  • .net MVC中使用angularJs刷新页面数据列表
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .net refrector
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [AX]AX2012 AIF(四):文档服务应用实例
  • [C++进阶篇]STL中vector的使用
  • [exgcd] Jzoj P1158 荒岛野人