跳至主要内容

归并排序的两种方式

概述

归并排序是目前最高效的排序算法之一,它兼具稳定和低复杂度的特点,其最坏时间复杂度O(nlogn),空间复杂度O(n)。

归并排序采用计算机科学的分治思想,因此有两种实现方式:自顶向下和自底向上。

自顶向下

针对分治问题,自顶向下是一张常见且较为简便的方式,它采用递归操作。

因此归并排序的原理也就清楚了,首先将数组拆分为两个,进行递归调用,然后合并排序结果。


这是一种可能的自顶向下C实现:

c
void merge(int arr[], unsigned sta, unsigned mid, unsigned end) { int tmp[end - sta]; unsigned i = sta, j = mid, k = 0; while (i < mid && j < end) { tmp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++]; } while (i < mid) { tmp[k++] = arr[i++]; } while (j < end) { tmp[k++] = arr[j++]; } for (size_t i = sta; i < end; i++) { arr[i] = tmp[i - sta]; } } void split_merge(int arr[], unsigned sta, unsigned end) { if (end - sta < 2) return; unsigned mid = (sta + end) / 2; split_merge(arr, sta, mid); split_merge(arr, mid, end); merge(arr, sta, mid, end); } void sort(int arr[], unsigned n) { split_merge(arr, 0, n); }

自底向上

自底向上与自上而下相反,从单个元素开始进行merge和排序,直至所有元素被merge。


这是一种可能的自底向上C实现,它与自顶向下使用相同的merge函数:

c
#define MIN(x, y) (((x) < (y)) ? (x) : (y)) void sort(int arr[], unsigned n) { for (size_t i = 1; i < n; i *= 2) { for (size_t j = 0; j < n; j += 2 * i) { merge(arr, j, MIN(j+i, n), MIN(j+i*2, n)); } } }

总结

两种方式都可以实现归并排序。

对于自底向上,由于免去递归,在n很大时,可以避免调用栈溢出。


评论

此博客中的热门博文

停更公告

为什么选择停下 随着AI时代的全面到来,我注意到几个深刻变化: 信息获取方式革命 :如今开发者更倾向于与AI对话解决问题,而非搜索博客文章 代码生成智能化 :GitHub Copilot、ChatGPT等工具正在改变编程本身 知识保鲜期缩短 :前端技术的半衰期越来越短,静态文章难以及时更新 互动形式进化 :实时编码、AI协作、视频教程成为更高效的学习方式 博客存档计划 所有历史文章将永久保留,供需要时查阅 评论区保持开放,我会偶尔回来看看 最后的话 技术博客的时代或许正在落幕,但技术分享的精神永存。只是形式在变——从静态文章到动态对话,从单向输出到双向协作。 这不是告别,而是换一种方式相遇。 在AI重构一切的时代,让我们以更智能的方式,继续探索前端的无限可能。

Web前端性能优化思路

首次发表于  Thoughtworks 洞见: https://insights.thoughtworks.cn/web-frontend-performance-tuning/ 掘金地址: https://juejin.cn/post/7206150468828135484

一次 AWS SageMaker 的上手体验

SageMaker 是个啥 用 AWS 官方的语言来说, SageMaker  是一个完全托管的机器学习平台。 作为一个并不懂机器学习,之前也没了解过 SageMaker 的小白,今天看了 AWS 中国“User Group 社区”的直播后,也亲自上手体验了一下 SageMaker。