数据结构【初阶】--排序(归并排序和基数排序)

目录

一.归并排序的非递归写法

1.思想应用 

2.代码基本实现 

(1)单趟归并逻辑 

(2)多趟(循环)的控制条件

① 迭代条件:i+=2*gap

② 结束条件:i(或i<=n-2*gap)<>

(3)代码展示 

① 单趟逻辑

②整体逻辑 

3.优化代码 

(1)end1和begin2越界 

(2)begin2不越界而end2越界

 二.计数排序

1.思想应用 

2.(直接映射)逻辑图示 

3.优点以及局限性 

4.针对分散的数据进行优化 

(1)(相对映射)图示解析 

(2)代码实现 


一.归并排序的非递归写法

1.思想应用 

采用思想:一个数肯定是有序的,就每一个数和另一个数归并成一个含有两个数的有序序列,然后一个含有两个数的有序序列在和另一个含有两个数的有序序列归并成一个含有四个数的有序序列,依次类推,最后整体有序。 

  • 图示 

 

2.代码基本实现 

(1)单趟归并逻辑 

  • 图示 

 

(2)多趟(循环)的控制条件

① 迭代条件:i+=2*gap
  • 图示 
② 结束条件:i<n(或i<=n-2*gap)

 

(3)代码展示 

① 单趟逻辑
    int* tmp = (int*)malloc(sizeof(int) * n);//开辟一个新数组if (tmp == NULL){perror("malloc fail");return;}int gap = 1;for (size_t i = 0;i<n;i+=2*gap){int begin1 = i,end1=i+gap-1;//第一组数据的首尾int begin2 = i + gap,end2=i+2*gap-1;//第二组数据的首尾//[begin1,end1][begin2,end2]--归并区间int j = begin1;while (begin1 <= end1 && begin2 <= end2){//小数向前调(尾插)if (a[begin1] < a[begin2]){tmp[j++] = a[begin1++];}//大数向后调(尾插)else{tmp[j++] = a[begin2++];}}//由于上面的begin1和begin2是分别向后走,一定有一个没走完//这里控制没走完的继续走while (begin1 <= end1){tmp[j++] = a[begin1++];}while (begin2 <= end2){tmp[j++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) *2*gap);//每归并两个数就拷贝回去}gap *= 2;
  • 效果 

 

②整体逻辑 
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}int gap = 1;while (gap < n)//控制多趟{for (size_t i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;//[begin1,end1][begin2,end2]--归并区间int j = begin1;while (begin1 <= end1 && begin2 <= end2){if (a[begin1] < a[begin2]){tmp[j++] = a[begin1++];}else{tmp[j++] = a[begin2++];}}while (begin1 <= end1){tmp[j++] = a[begin1++];}while (begin2 <= end2){tmp[j++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * 2 * gap);//每归并两个数就拷贝回去}gap *= 2;}free(tmp);
}
  • 效果演示 

 

  •  存在问题 

此样例给的数组数据个数恰好可以通过测试,但是代码本身存在问题导致其并不适用于所有样例,例如:

 我们观察一下分割的区间来看一看问题所在:

下面对代码进行改进。

3.优化代码 

(1)end1和begin2越界 

由于begin1=i,所以可以判断begin1是不可能越界的,那么越界的就可能是end1和begin2。(这里先不考虑begin2不越界而end2越界的情况。)

  • 解决方式 :发生越界时直接跳出循环
	if (end1 >= n || begin2 >= n)//begin2或end1越界{break;}

(2)begin2不越界而end2越界

  • 解决方式:修改end2的值,并且调整拷贝数据的大小 
//优化部分
if (end1 >= n || begin2 >= n)//begin2或end1越界
{break;
}
if (end2 >= n)
{end2 = n - 1;
}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));
  • 完整代码 
void MergeSortNonR(int* a, int n)
{int* tmp = (int*)malloc(sizeof(int) * n);if (tmp == NULL){perror("malloc fail");return;}int gap = 1;while (gap < n){for (size_t i = 0; i < n; i += 2 * gap){int begin1 = i, end1 = i + gap - 1;int begin2 = i + gap, end2 = i + 2 * gap - 1;//[begin1,end1][begin2,end2]--归并区间int j = begin1;if (end1 >= n || begin2 >= n)//begin2或end1越界{break;}if (end2 >= n){end2 = n - 1;}while (begin1 <= end1 && begin2 <= end2){if (a[begin1] <= a[begin2]){tmp[j++] = a[begin1++];}else{tmp[j++] = a[begin2++];}}while (begin1 <= end1){tmp[j++] = a[begin1++];}while (begin2 <= end2){tmp[j++] = a[begin2++];}memcpy(a + i, tmp + i, sizeof(int) * (end2-i+1));//每归并两个数就拷贝回去}gap *= 2;}free(tmp);
}
  • 效果 

 

 二.计数排序

1.思想应用 

思想:计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

操作步骤

  1. 统计相同元素出现次数
  2. 根据统计的结果将序列回收到原来的序列中 

2.(直接映射)逻辑图示 

 

 

3.优点以及局限性 

优点

  1. 效率极高
  2. 时间复杂度为O(aN+countN(有一个范围))

局限性

1.不适合分散的数据,更适合集中的数据

2.不适合浮点数、字符串、结构体数据排序,只适合整数

4.针对分散的数据进行优化 

(1)(相对映射)图示解析 

 

(2)代码实现 

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* count = (int*)calloc(range, sizeof(int));if (count == NULL){printf("calloc fail\n");return;}//统计次数for (int i = 0; i < n; i++){count[a[i] - min]++;}//排序int i = 0;for (int j = 0; j < range; j++){while (count[j]--){a[i++] = j + min;//把相对映射还原回去}}
}
  • 结果 

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL索引原理以及SQL优化

案例 struct index_failure_t{int id;string name;int cid;int score;string phonenumber;}Map<int,index_failure>; 熟悉C的同学知道&#xff0c;上述案例中&#xff0c;我们map底层是一颗红黑树&#xff0c;一个节点存储了一对kv&#xff08;键值对&#xff09;&…

07-Nacos-接入Mysql实现持久化

1、默认内嵌的数据库 Derby 存于/data目录 2、扩展仅支持Mysql 5.6.5 执行Nacos中的SQL脚本&#xff0c;该脚本是Nacos-server文件夹中的nacos-mysql.sql 详见 01-Nacos源码打包、部署-CSDN博客 3、修改配置文件 Nacos-server中的conf目录下&#xff0c;application.proper…

selenium总结-css 定位高级语法

文章目录 推荐的定位方式的优先级定位元素的注意事项&#xff08;划重点&#xff09;CSS选择器组成id 选择器class 选择器标签选择器分组选择器属性选择器组合选择符伪类最佳实践 推荐的定位方式的优先级 优先级最高&#xff1a;ID优先级其次&#xff1a;name优先级再次&#…

APT32F1023X 发送RF433处理

1.硬件电路--CMT2110A 需要注意&#xff1a;发射端MCU写数据的频率要匹配&#xff0c;如果MCU发送中时间最小脉宽是1MS&#xff0c;那么它的发送需要设置为1kbps。 通过华普微USB调试工具PC软件RFPDK_V1.55查看设置是否正确。 2.RF433发送 用到的发送和接收代码来自“无线433发…

状态接上一章

1.状态恢复 parceable pluginManagement {repositories {google()mavenCentral()gradlePluginPortal()}//插件plugins{id("com.android.application")version("7.1.0-alpha05")id("com.android.library")version("7.1.0-alpha05")id(…

【C/C++ 06】基数排序

基数排序是桶排序的一种&#xff0c;算法思路为&#xff1a; 利用队列进行数据收发创建一个队列数组&#xff0c;数组大小为10&#xff0c;每个元素都是一个队列&#xff0c;存储取模为1~9的数从低位到高位进行数据收发&#xff0c;完成排序适用于数据位不高的情况&#xff08…

HCIA-Datacom实验指导手册:4.1 实验一:访问控制列表配置实验,fragment分片acl演示。

HCIA-Datacom实验指导手册:4.1 实验一:访问控制列表配置实验 一、实验介绍:二、实验拓扑:三、实验目的:四、配置步骤:步骤 1 掌握ACL的配置方法 配置方法步骤 2 掌握 ACL在接口下应用方法步骤 3 掌握 流量过滤 的基本方式步骤 4 掌握 禁止分片报文通过的方法验证五、结果…

LeetCode——415. 字符串相加

C开头 &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️Take your time ! &#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#x1f32b;️&#x1f636;‍&#…

除了Adobe之外,还有什么方法可以将Excel转为PDF?

前言 Java是一种广泛使用的编程语言&#xff0c;它在企业级应用开发中发挥着重要作用。而在实际的开发过程中&#xff0c;我们常常需要处理各种数据格式转换的需求。今天小编为大家介绍下如何使用葡萄城公司的的Java API 组件GrapeCity Documents for Excel&#xff08;以下简…

《HTML 简易速速上手小册》第7章:HTML 多媒体与嵌入内容(2024 最新版)

文章目录 7.1 在HTML中嵌入视频和音频7.1.1 基础知识7.1.2 案例 1&#xff1a;嵌入视频文件7.1.3 案例 2&#xff1a;嵌入音频文件7.1.4 案例 3&#xff1a;创建一个视频和音频混合的播放列表 7.2 使用 <iframe> 嵌入外部内容7.2.1 基础知识7.2.2 案例 1&#xff1a;嵌入…

盒子模型的内容总结

知识引入 1.认识盒子模型 在浏览网站时我们会发现内容都是按照区域划分的。这使得网页很工整、美观。在页面中&#xff0c;每一块区域分别承载不同的内容&#xff0c;使得网页的内容虽然零散&#xff0c;但是在版式排列上依然清晰有条理。如图1 图1 *承载内容的区域称为盒子…

RabbitMQ常见生产问题详解

目录 RabbitMQ如何保证消息不丢失&#xff1f; 哪些环节会有丢消息的可能&#xff1f; RabbitMQ消息零丢失方案 1. 生产者保证消息正确发送到RibbitMQ 2. RabbitMQ消息存盘不丢消息 3. RabbitMQ 主从消息同步时不丢消息 4. RabbitMQ消费者不丢失消息 如何保证消息幂等&…