基础的排序算法下(交换排序和归并排序)

news/2025/3/4 14:30:41/

1:交换排序

基本思想:所谓交换,就是根据序列中两个记录键值的⽐较结果来对换这两个记录在序列中的位置 交换排序的特点是:将键值较⼤的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

1:冒泡排序(每个计算机学生必掌握的第一个算法

直接看代码吧,太简单不讲了

void BubbleSort(int* a, int n)
{for (int i = 0; i < n; i++){for (int j = 0; j < n - i - 1; j++){if (a[j] > a[j+1]){Swap(&a[j], &a[j+1]);}}}
}

2:快速排序(递归版本)

快速排序是Hoare于1962年提出的⼀种⼆叉树结构的交换排序⽅法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两⼦序列,左⼦序列中所有元素均小于基准值,右子序列中所有元素均⼤于基准值,然后最左右⼦序列重复该过程,直到所有元素都排列在相应位置上为止。(本质上是找基准数)

我们先把主题void函数写出来

void QuickSort(int* a, int left, int right)
{if (left >= right){return;}int keyi = PartSort(a, left, right);//找基准值函数QuickSort(a, left, keyi - 1);QuickSort(a, keyi + 1, right);
}
1:快速排序hoare版本
int PartSort1(int* a, int left, int right)
{int keyi = left;++left;while (left <= right){while (left <= right && a[right] > a[keyi]){--right;}while (left <= right && a[left] < a[keyi]){++left;}if (left <= right){Swap(&a[right--], &a[left++]);}}Swap(&a[keyi], &a[left-1]);return left-1;
}

基本思路:

1:创建左右指针,确定基准值

2:从右向左找出⽐基准值⼩的数据,从左向右找出⽐基准值⼤的数据,左右指针数据交换,进⼊下次循环

2:快速排序挖空法
int PartSort2(int* a, int left, int right)
{int hole = left;int key = a[hole];while (left < right){while (left<right && a[right]>=key){--right;}a[hole] = a[right];hole = right;while (left < right && a[left] <=key){left++;}a[hole] = a[left];hole = left;}a[hole] = key;return hole;
}

基本思路:

创建左右指针。⾸先从右向左找出⽐基准⼩的数据,找到后⽴即放⼊左边坑中,当前位置变为新的"坑",然后从左向右找出⽐基准⼤的数据,找到后⽴即放⼊右边坑中,当前位置变为新的"坑",结束循环后将最开始存储的分界值放⼊当前的"坑"中,返回当前"坑"下标(即分界值下标)

3:快速排序前后指针法
int PartSort3(int* a, int left, int right)
{int keyi = left;int prev = left, cur = prev + 1;while (cur <= right){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[prev], &a[cur]);}++cur;}Swap(&a[prev], &a[keyi]);return prev;
}

基本思路:

创建前后指针,从左往右找比基准值小的进行交换,使小的都排在基准值左边。

3:快速排序(非递归版本借助stack实现)

void QuickSortNonR(int* a, int left, int right)
{Stack st;StackInit(&st);StackPush(&st, right);StackPush(&st, left);while (!StackEmpty(&st)){int begin = StackTop(&st);StackPop(&st);int end = StackTop(&st);StackPop(&st);int keyi = begin;int prev = begin, cur = prev + 1;while (cur <= end){if (a[cur] < a[keyi] && ++prev != cur){Swap(&a[prev], &a[cur]); }cur++;}Swap(&a[prev], &a[keyi]);keyi = prev;if (keyi + 1 < end)   {StackPush(&st, end);  StackPush(&st, keyi + 1); }if (begin < keyi - 1){StackPush(&st, keyi - 1);StackPush(&st, begin);}}StackDestroy(&st);
}

2:归并排序

1:归并排序递归实现

void _MergeSort(int* arr, int left, int right, int* tmp)//辅助函数
{if (left >= right){return;}int mid = (left + right) / 2;_MergeSort(arr, left, mid, tmp);_MergeSort(arr, mid + 1, right, tmp);int begin1 = left, end1 = mid;int begin2 = mid + 1, end2 = right;int index = begin1;while (begin1 <= end1 && begin2 <= end2){if (arr[begin1] < arr[begin2]){tmp[index++] = arr[begin1++];}else{tmp[index++] = arr[begin2++];}}while (begin1 <= end1){tmp[index++] = arr[begin1++];}while (begin2 <= end2){tmp[index++] = arr[begin2++];}for (int i = left; i <= right; i++){arr[i] = tmp[i];}
}void MergeSort(int* a, int n)//声明
{int* tmp = (int*)malloc(sizeof(int) * n);_MergeSort(a, 0, n - 1, tmp);free(tmp);
}

基本思路:归并排序(MERGE - SORT)是建⽴在归并操作上的⼀种有效的算法>排序算法, 该算法是采⽤分治法(Divideand Conquer)的⼀个⾮常典型的应⽤。将已有序的⼦序列合并,得到完全有序的序列;即先使每个⼦序列有序,再使⼦序列段间有序。若将两个有序表合并成⼀个有序表,称为⼆路归并。 

2:归并排序非递归实现

void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");exit(1);}int gap = 1;while (gap < n){for (int i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;if (begin2 >= n){break;}if (end2 >= n){end2 = n-1;}int index = begin1;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[index++] = a[begin1++];}else{tmp[index++] = a[begin2++];}}while (begin1 <= end1){tmp[index++] = a[begin1++];}while (begin2 <= end2){tmp[index++] = a[begin2++];}memcpy(a+i, tmp+i, sizeof(int) * (end2 - i + 1));}gap *= 2;}free(tmp);tmp = NULL;
}

3:计数排序(非比较排序)

void CountSort(int* a, int n)
{int min = a[0], max = a[0];for (int i = 1; i < n; i++){if (a[i] < min){min = a[i];}if (a[i] > max){max = a[i];}}int range = max - min + 1;int* cout = (int*)malloc(sizeof(int) * range);if (cout == NULL){perror("malloc fail");}memset(cout, 0, sizeof(int) * range);for (int i = 0; i < n; i++){cout[a[i] - min]++;}int index = 0;for (int i = 0; i < range; i++){while (cout[i]--){a[index++] = i + min;}}
}
计数排序⼜称为鸽巢原理,是对哈希直接定址法的变形应⽤。 操作步骤:
1:统计相同元素出现次数
2:根据统计的结果将序列回收到原来的序列中

http://www.ppmy.cn/news/1576563.html

相关文章

FPGA_YOLOv3

B为多少个候选框&#xff0c; 5为5个位置信息 C为多少个类别 v3d的损失函数&#xff1a; 第一行 位置误差 用了BCE损失函数 正样本的选取 就是在这个标注框里面的中心点有很多个预测框&#xff0c;选取与图片的iou的最大值作为正样本。

vue2+ele-ui实践

前言&#xff1a;真理先于实践&#xff0c;实践发现真理&#xff0c;再实践检验真理 环境&#xff1a;vue2 & element-ui 正片&#xff1a; Select 选择器 简称 下拉框 下拉框完整的使用循环 下拉框 → 点击下拉框 → 展示数据 → 选择数据 → 下拉框显示数据 核心具有…

Ubuntu 系统下安装 Nginx

目录 一、Nginx是什么 ?二、Ubuntu 系统下安装 Nginx 1、安装包下载 2、上传服务器并解压缩 3、依赖配置安装 4、生成编译脚本 ?5、编译 6、开始安装 7、设置为随机自启动 7.1、创建 nginx.service 文件&#xff0c;将以下内容粘贴到文件中 7.2、将 nginx.service…

CST的UAV无人机RCS --- 双站, I求解器,CAD切割,PEC吸波材料涂层

之前几期无人机案例都是用的PEC&#xff0c;这期我们看看添加雷达吸波材料图层的PEC对RCS的影响。使用RCS模板&#xff0c;0.4GHz添加一些场监视器&#xff1a; 导入CAD模型&#xff0c;这个尺寸是11.6米长。调制参数栏&#xff0c;使入射波从飞机下面向上入射&#xff0c;极化…

一、Redis 基础入门:概述与应用场景

Redis 基础入门:概述与应用场景 在现代应用开发中,高性能、高并发的数据访问需求越来越强烈,传统的关系型数据库(如 MySQL)在某些场景下难以满足这些需求。Redis 作为一款高性能的内存数据库(In-Memory Database),凭借极快的读写速度、丰富的数据结构和强大的扩展能力…

C语言:51单片机 程序设计基础

C51常用进制转换 C51常用的数据类型 注&#xff1a;c51单片机中因为是8位的在实际使用过程中 float和double的用法是一模一样。 特别说明&#xff1a;unsigned无符号和signed有符号型的取值范围。 bit位标量 bit位标量是C51编译器的一种扩充数据类型。可以定义一个位标量&…

开放鸿蒙OpenHarmony 5.0.0 Release 兼容性测试实战经验分享

OpenHarmony 5.0版本的发布时间是2024年12月20日至21日。这个版本带来了许多新特性和改进。现在5.0出了两个release 版本&#xff0c;分别是5.0.0和5.0.1。 就在5.0版本发布不到2周的时间内&#xff0c;2025年01月01日起&#xff0c;不支持新产品基于老分支&#xff08;OpenHar…

阿里云物联网获取设备属性api接口:QueryDevicePropertyData

阿里云物联网接口&#xff1a;QueryDevicePropertyData 说明&#xff1a;调用该接口查询指定设备或数字孪生节点&#xff0c;在指定时间段内&#xff0c;单个属性的数据 比如提取上传到物联网的温度数据 api文档&#xff1a;QueryDevicePropertyData_物联网平台_API文档-阿里…