当前位置:网站首页>归并排序和非比较排序
归并排序和非比较排序
2022-07-07 05:25:00 【老鱼37】
归并排序还是比较难理解的,我们要掌握归并排序的递归和非递归的方式。
下面先了解一下归并排序到底是什么:
四个字----分而治之
先从整体小的归并,然后到总的整体归并

完整代码:
void _MerGetSort(int* arr, int begin, int end, int* tmp)
{
if (begin >= end)
{
return;
}//划分区域
int mid = (begin + end) / 2;
//递归
_MerGetSort(arr, begin, mid, tmp);
_MerGetSort(arr, mid + 1, end, tmp);
//归并比较
int begin1 = begin;
int end1 = mid;
int begin2 = mid + 1;
int end2 = end;
int i = begin1;
while (begin1 <= end1 && begin2 <= end2)
{
if (arr[begin1] < arr[begin2])
{
tmp[i++] = arr[begin1++];
}
else
{
tmp[i++] = arr[begin2++];
}
}
//肯定有一个已经走完了 将剩下的归并到tmp中
while (begin1 <= end1)
{
tmp[i++] = arr[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = arr[begin2++];
}//归并完了,将tmp拷贝回arr数组
memcpy(arr + begin, tmp + begin, sizeof(int) * (end - begin + 1));
}void MerGetSort(int* arr, int len)
{
//开辟一个数组
int* tmp = (int *)malloc(sizeof(int) * len);
_MerGetSort(arr, 0, len - 1, tmp);
free(tmp);
}
void PrintSort(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 3,1,2,4,9,5,6};
int len = sizeof(arr) / sizeof(arr[0]);
MerGetSort(arr, len);
PrintSort(arr, len);
}
下面介绍非递归写法:
void MerGetSort(int* arr, int len)
{
//开辟一个新的数组
int* tmp = (int*)malloc(sizeof(int) * len);
if (tmp == NULL)//判断一下
{
printf("malloc fail\n");
exit(-1);
}
int gap = 1;//确定gap
while (gap < len)
{
printf("%d->", gap);
for (int i = 0; i < len; i += 2 * gap)
{
//[i, i + gap - 1] [gap + i, i + 2 * gap - 1] 划分区域
int begin1 = i, end1 = i + gap - 1;
int begin2 = gap + i, end2 = i + 2 * gap - 1;
printf("[%d][%d] [%d][%d]", begin1, end1, begin2, end2);
//判断越界区域,然后修改
//因为gap是多少begin1都会是最后一个,所以从end1开始修改
if (end1 >= len)
{
end1 = len - 1;
begin2 = len; //此时[begin2,end2]----[len,len-1]不合理,就不会执行
end2 = len - 1;
}
else if (begin2 >= len)//无效区域 修改
{
begin2 = len;
end2 = len - 1;
}
else if (end2 >= len)
{
end2 = len - 1;
}
int i = begin1;
//然后归并比较
while (begin1 <= end1 && begin2 <= end2)
{
if (arr[begin1] < arr[begin2])
{
tmp[i++] = arr[begin1++];
}
else
{
tmp[i++] = arr[begin2++];
}
}
//走完之后,将剩下的数据放入tmp
while (begin1 <= end1)
{
tmp[i++] = arr[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = arr[begin2++];
}
}
printf("\n");
memcpy(arr, tmp, sizeof(int) * len);//拷贝
gap = gap * 2;
}
}
void PrintSort(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 3,1,2,4,9,5,6};
int len = sizeof(arr) / sizeof(arr[0]);
MerGetSort(arr, len);
PrintSort(arr, len);
}
至于无效区域是指:
如果你不想修改边界的话,也可以直接跳过,修改如下:
方法二:
这么memcpy是一段一段拷贝的,不想方式一是全部一起拷贝,两种方式看个人喜好。
接下来要介绍的是非比较排序

我们接下来学的就是计数排序
了解一下计数排序

这种计数排序具有局限性:
1、如果是浮点数,字符串就不能玩了
2、如果数据范围很大,空间复杂度就会很高,也不能玩
3、一般这些数据都是相差的幅度比较小
当遇到100、1000以上这些数据,又相差不大的话,运用相对映射的话就非常实用了。
//计数排序
void CountSort(int* arr, int len)
{
int min = arr[0], max = arr[0];//最小最大的都是第一位 往后面去找
for (int i = 1; i < len; i++)
{
if (arr[i] < min)
{
min = arr[i];
}
if (arr[i] > max)
{
max = arr[i];
}
}
//最大最小已经找好了 开辟空间
int range = max - min + 1;
int* count = (int *)malloc(sizeof(int) * range);
if (count == NULL)
{
printf("malloc fail\n");
exit(-1);
}
memset(count, 0, sizeof(int) * range);//全部初始化成0//统计出现次数
for (int i = 0; i < len; i++)
{
count[arr[i] - min]++;
}//回写排序
int j = 0;
for (int i = 0; i < range; i++)
{
while (count[i]--)
{
arr[j++] = i + min;
}
}
}
void PrintSort(int* arr, int len)
{
for (int i = 0; i < len; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 1003,1001,1002,1004,1009,1005,1006};
int len = sizeof(arr) / sizeof(arr[0]);
CountSort(arr, len);
PrintSort(arr, len);
}

这里对前面几种排序作归类,和有缺点评估


希望小伙伴们都能学会这些排序,你们的支持才是我前进的动力呀!
如有错误,多多指教!
边栏推荐
- 轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷
- Wang Zijian: is the NFT of Tencent magic core worth buying?
- Rainbond结合NeuVector实践容器安全管理
- Basic use of CTF web shrink template injection nmap
- Openjudge noi 2.1 1752: chicken and rabbit in the same cage
- Hisense TV starts the developer mode
- Réplication de vulnérabilité - désrialisation fastjson
- The truth of robot education in hands-on practice
- opencv学习笔记一——读取图像的几种方法
- Call pytorch API to complete linear regression
猜你喜欢

Real time monitoring of dog walking and rope pulling AI recognition helps smart city

Vulnerability recurrence fastjson deserialization
![[step on the pit series] H5 cross domain problem of uniapp](/img/53/bd836a5c5545f51be929d8d123b961.png)
[step on the pit series] H5 cross domain problem of uniapp

BiSeNet的特點

opencv学习笔记五——梯度计算/边缘检测

opencv学习笔记四——膨胀/腐蚀/开运算/闭运算

Uniapp mobile terminal forced update function

Myabtis_ Plus

What is the function of paralleling a capacitor on the feedback resistance of the operational amplifier circuit

opencv学习笔记三——图像平滑/去噪处理
随机推荐
IP-guard助力能源企业完善终端防泄密措施,保护机密资料安全
在 Rainbond 中一键安装高可用 Nacos 集群
接口作为参数(接口回调)
Lua 编程学习笔记
Famine cloud service management script
提高企业产品交付效率系列(1)—— 企业应用一键安装和升级
Using nocalhost to develop microservice application on rainbow
Vulnerability recurrence fastjson deserialization
Rainbond 5.7.1 支持对接多家公有云和集群异常报警
雅思考试自己的复习进度以及方法使用【日更版】
Rainbond结合NeuVector实践容器安全管理
One click deployment of highly available emqx clusters in rainbow
通俗易懂单点登录SSO
JS cross browser parsing XML application
Complex network modeling (I)
Complex network modeling (III)
Zcmu--1492: problem d (C language)
CCTV is so warm-hearted that it teaches you to write HR's favorite resume hand in hand
Snyk 依赖性安全漏洞扫描工具
Basic use of CTF web shrink template injection nmap
