八股文之八大排序(C++)

news2024/11/22 16:52:06

目录

1.直接插入排序

2.希尔排序

3.简单选择排序

4.堆排序

5.冒泡排序

6.快速排序

7.归并排序

8.基数排序(桶排序)

9.主函数

10.画图总结


1.直接插入排序

int ai[] 为需要排序的数组

start 为起始位置,要求 start>=1 ,因为 ai[0] 要作为“哨兵”使用。

end 为结束位置

代码思路:看后面的数字有没有比前面的大,比前面的大则需要插入交换,从后往前,依次比较,依次往后移一位,直到不满足

void InsertSort(vector<int>&arr, int len)
{
	int tmp = 0;
	for (int i = 1; i < len; i++)//第一张扑克牌无需比较
	{
		tmp = arr[i];
		if (arr[i] < arr[i - 1])//满足需要交换的条件
		{
			for (int j = i - 1; j >= 0&&arr[j]>tmp; j--)//这里多加了一个判断,因为之前if语句进入之后,第一次循环没有问题,但当第二次及之后的循环开始,没有这个判断,代码会直接交换,不在乎大小
			{
				arr[j+1] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}

2.希尔排序

希尔排序:进阶版的直接插入排序

  • 原理:将一组数进行分组,比如按5 3 1分组,就是开始五个数为一组,再3个数,最后一个数,分组后,每一组的第一个相互比较,观察满不满足交换条件,依次第二个、第三个,直到这个分组的数比较完成,再开始下一个分组

  • 算法的优点在于它首先保证局部的大致有序,让最后的直接插入排序交换的次数减少

void ShellSort(vector<int>& arr, int len)
{
    int inc = 0, i = 0, j = 0, tmp = 0;
  //inc是初始增量,每次除2
   for (inc = len / 2; inc >0; inc /= 2)
   {
	//插入排序
	   for (i = inc; i < len; i++)
	   {
		   tmp = arr[i];
		   for (j = i; j >= inc&&tmp<arr[j-inc]; j-=inc)
		  {
			  arr[j] = arr[j-inc];
		   }
           arr[j] = tmp;
	   }
    }
}

3.简单选择排序

简单选择排序:一直寻找剩余数组中最小的元素放到前面

void SelectSort(vector<int>& arr, int len)
{
	int tmp = 0;
	for (int i = 0; i < len - 1; i++)
	{
		for (int j = i + 1; j < len; j++)
		{
			if (arr[i] > arr[j])//因为这里一直是和i所在位置的元素比,所以不是像冒泡排序一样全部用j
			{
				tmp = arr[j];
				arr[j] = arr[i];
				arr[i] = tmp;
			}
		}
	}
}

4.堆排序

  • 堆排序:堆调整+堆排序

  • 将最开始的数组构建完全二叉树,通过堆调整让最大的数出现在根节点上,交换根节点与最后一个节点,将除最后一个节点的其他数再次调整,最大的数位于根节点,以此类推

void Adjust(vector<int>& arr, int len, int index)
{
	int left = 2 * index + 1;//左孩子
	int right = 2 * index + 2;//右孩子
	int maxIdx = index;
	if (left<len && arr[left]>arr[maxIdx])maxIdx = left;
	if (right<len && arr[right]>arr[maxIdx])maxIdx = right;//经过两个if判断后,maxIdx是父节点以及两个叶子节点之中最大值的下标

	if (maxIdx != index)//maxIdx如果发生变化
	{
		swap(arr[maxIdx], arr[index]);//交换下标对应的值,让最大值处于根节点
		Adjust(arr, len, maxIdx);//继续调整
	}
}
void HeapSort(vector<int>&arr,int len)
{
	for (int i = len / 2 - 1; i >= 0; i--)
	{
		Adjust(arr, len, i);//从最下层的非叶子节点开始调整

	}
	for (int i = len - 1; i >= 1; i--)//这里i不取0是因为剩余一个数的时候不用交换
	{
		swap(arr[0], arr[i]);//根节点的数与结尾的数进行交换,再次循环去调整
		Adjust(arr, i, 0);//寻找最大的数放到根节点,重复以上步骤

	}
}

5.冒泡排序

比较相邻的元素。如果第一个比第二个大,就交换他们两个。

对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。

针对所有的元素重复以上的步骤,除了最后一个。

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

void BubbleSort(vector<int>& ai, int len)
{
	int i = 0, j = 0,tmp=0;
	for (i=0; i < len-1; ++i)//比如10个数只用9趟排序就可以
	{
		for (j=0;j < len -1-i; j++)
		{
			if (ai[j] > ai[j + 1])
			{
				 tmp = ai[j];
				ai[j] = ai[j + 1];
				ai[j + 1] = tmp;
			}
		}
	}
}

6.快速排序

划分函数+递归调用

  • 以第一个数为基准,将所有数按照基准划分左右,左边小,右边大,对左子序列和右子序列重复以上操作

 int Part(vector<int>& arr, int low, int high)
{
	int pivot = arr[low];//一般以第一个数为基准
	int i = low, j = high;
	while (i < j)
	{
		while (i < j && arr[j] > pivot)
		{
			j--;
		}
		if (i < j)//走到这说明上个while循环的第二个条件是不满足的
		{
			swap(arr[i], arr[j]);
			i++;
		}
		while (i < j && arr[i] <= pivot)
		{
			i++;
		}
		if (i < j)
		{
			swap(arr[i], arr[j]);
			j--;
		}
	}
	return i;//返回最后基准划分所在的下标
}
void QuickSort(vector<int>& arr, int left, int right)
{
	int mid = 0;
	if (left < right)
	{
		mid = Part(arr, left, right);
		QuickSort(arr, left, mid - 1);//等到这里失败才会进行下面的递归,所以 这里失败的时候就是已经有序的情况
		QuickSort(arr, mid + 1, right);
	}
}

7.归并排序

归并排序:将数组进行分组,保证组内有序,分成最小的组也就是一个数组一组,因为默认一个数字就是有序,所以开始两两一组排序,有序的合并两两一组就变成了四个数一组,依次递增,直到最后合并为一组

void Merge(vector<int>& arr,int *temp, int left, int mid, int right)
{
	
	int k = left, i = left, j = mid + 1;
	while (i != mid+1 && j <= right)
	{
		if (arr[i] <= arr[j])temp[k++] = arr[i++];
		else
		{
			temp[k++] = arr[j++];
		}

	}
	while (i <= mid)
	{
		temp[k++] = arr[i++];//右边数据已经放完,将左边已经有序的数据放入temp中
	}
	while (j <= right)
	{
		temp[k++] = arr[j++];//左边数据已经放完
	}

	for (int i= 0;i< k ; i++)
	{
		arr[i] = temp[i];
	}
	
}
void MergeSort(vector<int>& arr,int *temp, int left, int right)
{
	if (left == right)
	{
		return;
	}
	else
	{
		int mid = left + (right-left) / 2;
		MergeSort(arr, temp,left, mid);
		MergeSort(arr,temp, mid + 1, right);
		Merge(arr,temp,left, mid, right);
	}
}

8.基数排序(桶排序)

以最大的数的位数为标准,比如最大数是255,最高位是百位,那么就进行三次排列,将每个数的个位放入对应的桶,桶从0-9,比如277,第一步个位为7,所以放入下标为7的桶中,依次放入所有的数,由于可能有多个数的个位相同,所以这个桶是一个二维数组;最后把二维数组里的数又放回原始数组里,完成第一趟排序,但这样存在一个问题就是有些桶可能没有数据,不需要遍历,所以增加一个数组bucketIndex来记录每个桶内放入多少数据;遍历的时候加上这个限制,最后,把下标桶(bucketIndex)中的数据清零,至此,完成了第一次排序。

void RadixSort(vector<int>& arr, int len)
{
	//1.找出最大值
	int max = arr[0];
	int bucket[10][1000];//这里必须给常量值,这个二维数组是存放数据的数组
	int bucketIndex[] = { 0,0,0,0,0,0,0,0,0,0 };//记录0-9这些桶里是否有数据
	for (int i = 1; i < len; i++)
	{
		max = arr[i] > max ? arr[i] : max;
	}
	int divisor = 1;//控制最大数获取各个位的数,比如获取个位除1然后%10就可,获取十位就是除以10然后%10
	//2.循环找出最大值的位数
	while (max > 0)
	{
       //遍历数组放入桶中
		for (int i = 0; i < len; i++)
		{
			int temp = arr[i]/divisor%10;//依次求出这个数的个位十位等
			bucket[temp][bucketIndex[temp]] = arr[i];
			bucketIndex[temp]++;//计数加加

		}
		//3.把桶中的数据重新赋值给原始数组
		int index = 0;
		for (int i = 0; i < 10; i++)
		{
			if (bucketIndex[i] != 0)//代表有数据
			{
				for (int j = 0; j < bucketIndex[i]; j++)
				{
					arr[index++] = bucket[i][j];
				}
			}
		}
		//4.清空下标桶
		for (int i = 0; i < 10; i++)
		{
			bucketIndex[i] = 0;
		}

		divisor *= 10;
		max /= 10;
	}

}

9.主函数

void main()
{
	int ar[] = { 8, 1,200, 14, 3, 21, 5, 7, 10 ,0};
	int len = sizeof(ar) / sizeof(ar[0]);
	vector<int>arr(ar, ar +len);
	int* brr = new int[len];
	
	BubbleSort(arr, len);//冒泡排序
	cout << "冒泡排序:      ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	InsertSort(arr, len);//直接插入
	cout << "直接插入排序:  ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	ShellSort(arr, len);//希尔排序
	cout << "希尔排序:      ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	SelectSort(arr, len);//简单选择排序
	cout << "简单选择排序:  ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	HeapSort(arr, len);//堆排序
	cout << "堆排序:        ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	QuickSort(arr, 0, len - 1);//快速排序
	cout << "快速排序:      ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	MergeSort(arr,brr, 0, len-1);//归并排序
	cout << "归并排序:      ";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	RadixSort(arr, len);//基数(桶)排序
	cout << "基数(桶)排序:";
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << "    ";
	}
	cout << endl;
	delete[]brr;
	brr = nullptr;
}

截图:

 

10.画图总结

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/894018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python基础4——类、异常处理、常用模块

文章目录 一、类二、python异常处理三、自定义模块3.1 保留模块测试代码3.2 添加模块使用说明 四、内置模块4.1 os标准库4.2 os.path类4.3 sys库4.4 platform库4.5 glob库4.6 random库4.7 subprocess库4.8 pickle库4.9 JSON库4.10 time库4.11 datetime库4.12 urllib库4.12.1 re…

Unity Android 之 使用 HanLP 进行句子段落的分词处理(包括词的属性处理)的简单整理

Unity Android 之 使用 HanLP 进行句子段落的分词处理&#xff08;包括词的属性处理&#xff09;的简单整理 目录 Unity Android 之 使用 HanLP 进行句子段落的分词处理&#xff08;包括词的属性处理&#xff09;的简单整理 一、简单介绍 二、实现原理 三、注意事项 四、效…

水泥厂人员定位方案

水泥厂人员定位方案可以采用不同的技术和策略。以下是一个常见的水泥厂人员定位方案的步骤&#xff1a; 1.选择合适的定位技术&#xff1a;根据水泥厂的需求和运营环境&#xff0c;选择适合的定位技术&#xff0c;例如基于UWB&#xff08;Ultra-Wideband&#xff09;、RFID&am…

无涯教程-Perl - undef函数

描述 此函数未定义EXPR的值。用于标量,列表,哈希,函数或类型范围。在带有诸如undef $hash {$key}之类的语句的哈希上使用&#xff1b;实际上将指定键的值设置为未定义的值。 如果要从哈希中删除元素,请使用delete函数。 语法 以下是此函数的简单语法- undef EXPRundef返回…

windows ipv4 多ip地址设置,默认网关跃点和自动跃点是什么意思?(跃点数)

文章目录 Windows中的IPv4多IP地址设置以及默认网关跃点和自动跃点的含义引言IPv4和IPv6&#xff1a;简介多IP地址设置&#xff1a;Windows环境中的实现默认网关跃点&#xff1a;概念和作用自动跃点&#xff1a;何时使用&#xff1f;关于“跃点数”如何确定应该设置多少跃点数&…

【3Ds Max】布料命令的简单使用

简介 在3ds Max中&#xff0c;"布料"&#xff08;Cloth&#xff09;是一种模拟技术&#xff0c;用于模拟物体的布料、织物或软体的行为&#xff0c;例如衣物、帆布等。通过应用布料模拟&#xff0c;您可以模拟出物体在重力、碰撞和其他外力作用下的变形和动态效果。…

【学习FreeRTOS】第11章——FreeRTOS中任务相关的其他API函数

1.函数总览 序号函数描述1uxTaskPriorityGet()获取任务优先级2vTaskPrioritySet()设置任务优先级3uxTaskGetNumberOfTasks()获取系统中任务的数量4uxTaskGetSystemState()获取所有任务的状态信息5vTaskGetInfo()获取单个任务的状态信息6xTaskGetCurrentTaskHandle()获取当前任…

利用Velero对K8S备份还原与集群迁移实战

一、简介 Velero 是一款云原生时代的灾难恢复和迁移工具&#xff0c;采用 Go 语言编写&#xff0c;并在 github 上进行了开源&#xff0c;利用 velero 用户可以安全的备份、恢复和迁移 Kubernetes 集群资源和持久卷。 开源地址&#xff1a;https://github.com/vmware-tanzu/v…

Element通过v-for循环渲染的form表单校验

需求&#xff1a;有个表单信息是v-for渲染的&#xff0c;例如下图&#xff0c;通过循环遍历实现新增和删除模块&#xff0c;按照平时的写法实现校验&#xff0c;是不能实现我们想要的效果&#xff0c;根据这个需求&#xff0c;我找到了一个解决方法 1.HTML <el-form ref&qu…

【抓包工具】whistle抓包工具分享

一、使用场景 抓包请求转发 二、基础篇 官网&#xff1a;http://wproxy.org/whistle/ github: https://github.com/avwo/whistle 简介&#xff1a; whistle(读音[ˈwɪsəl]&#xff0c;拼音[wēisǒu])基于Node实现的跨平台web调试代理工具&#xff0c;类似的工具有Window…

React 之 Router - 路由详解

一、Router的基本使用 1. 安装react-router react-router会包含一些react-native的内容&#xff0c;web开发并不需要 npm install react-router-dom 2. 设置使用模式 BrowserRouter或HashRouter Router中包含了对路径改变的监听&#xff0c;并且会将相应的路径传递给子组件Bro…

优化视频流:利用美颜SDK提升直播质量的方法

随着互联网的迅猛发展&#xff0c;视频直播已成为人们分享、交流和娱乐的重要方式。然而&#xff0c;在实际的直播过程中&#xff0c;视频画质可能受到诸多因素的影响&#xff0c;例如摄像头品质、网络状况等。为了提升观众的体验和吸引更多的观众&#xff0c;美颜技术逐渐成为…

8.18号transformer 系列文章阅读

文章目录 STGM: Spatio-Temporal Graph Mixformer for Traffic ForecastingAttention Is Not All You Need AnymoreLEARNING IMAGE DERAINING TRANSFORMER NETWORK WITH DYNAMIC DUAL SELF-ATTENTIONSST: A Simplified Swin Transformer-based Model for Taxi Destination Pred…

zookeeper安装配置采坑流程

安装 wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.2/apache-zookeeper-3.8.2-bin.tar.gz解压&#xff1a; tar -zxvf apache-zookeeper-3.8.2-bin.tar.gz如下 bin目录下文件是可执行文件 conf目录文件是配置文件 修改zoo.cfg&#xff08;复制zoo_sample&#x…

python生成器有几种写法,python生成器函数例子

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python生成器有几种写法&#xff0c;python生成器函数例子&#xff0c;今天让我们一起来看看吧&#xff01; 本文部分参考&#xff1a;Python迭代器&#xff0c;生成器–精华中的精华 https://www.cnblogs.com/deeper/p…

C#接化发:串口通信

文章目录 框架准备串口准备接、化、发测试 源码地址&#xff1a;C# 串口通信测试软件 框架准备 出于简单考虑&#xff0c;首先创建一个Winform项目&#xff0c;本文项目名称为portTest。 串口通信&#xff0c;至少有两个串口才能通信&#xff0c;所以拖动两个GroupBox&#…

Python 3 使用Hive 总结

启动HiveServer2 服务 HiveServer2 是一种可选的 Hive 内置服务&#xff0c;可以允许远程客户端使用不同编程语言向 Hive 提交请求并返回结果。 Thrift服务配置 假设我们已经成功安装了 Hive&#xff0c;如果没有安装&#xff0c;请参考&#xff1a;Hive 一文读懂 。在启动 H…

SAP后台表SE16和SE16N修改后台表数据方法

SAP后台表SE16和SE16N修改后台表数据方法 SAP中直接修改表、视图的Tcode有SE16N和SM30。 一 . SE16N界面输入&SAP_EDIT 其中使用SE16N修改表需要先输入命令&SAP_EDIT,回车左下角显示激活SAP编辑功能后&#xff0c;就可以对相应的表进行新增、删除、修改的操作。 有…

剑指offer44.数字序列中某一位的数字

最后一道题&#xff0c;我一定要自己做出来&#xff0c;想了不到一个小时想法差不多成熟了&#xff0c;但是有一个小细节出问题了&#xff0c;这个问题我在idea上debug都没debug出来。我先讲我的题解然后再讲我这个小问题出在哪里吧。以下是我的代码&#xff1a; class Soluti…

基于.Net Core开发的医疗信息LIS系统源码

SaaS模式.Net Core版云LIS系统源码 医疗信息LIS系统是专为医院检验科设计的一套实验室信息管理系统&#xff0c;能将实验仪器与计算机组成网络&#xff0c;使病人样品登录、实验数据存取、报告审核、打印分发&#xff0c;实验数据统计分析等繁杂的操作过程实现了智能化、自动化…