这一次我们要介绍的是一种元素比较次数较少、比较有效的 自底向上合并排序算法。
假设要对这8个数字的数字排序:9, 4, 5, 2, 1, 7, 4, 6
考虑下面的这个排序方法
首先将输入元素分成4对(8个),合并每对为一个2元素的排序序列,然后将每两个连续的2元素的序列合并成大小为4的排序序列,最后将两个排序序列合并成途中所示的最终的排序序列。
我们这里设A为需要排序的n个元素的数组,首先合并⌊n/2⌋个连续元素对,生成大小为2的⌊n/2⌋排序序列,如果剩余一个元素,就让它进入下一轮迭代。
然后合并⌊n/4⌋个连续的2元素对的序列,生成⌊n/4⌋个大小为4的排序序列,如果剩余一个或者两个元素,就让它们进入下一轮迭代;如果剩余三个元素,将两个已排序的元素和另一个元素合并成一个3元素的排序序列。
继续这个过程,在第i次迭代中,合并⌊n/2i⌋对大小为2i-1的排序序列,生成大小为2i的⌊n/2i⌋个排序序列。如果有k个剩余元素(1 ≤ k ≤ 2i-1),就将他们放在下一次合并中;如果有k个剩余元素(2i-1 < k < 2i),就将它们合并,形成一个大小为k的排序序列。
结合这张图也许你会理解得更加清楚
算法BottomUpSort 的思想实现了这张图的组合过程。
先用变量 mergeSize 存储被合并序列的大小,开始时将 mergeSize 置为1,每次执行外边的 while 循环时被乘以2。
low, middle, high 用来定义两个要排序的序列的边界(方便调用之前讲过的 Merge 算法)。
当 arrayLength 不是 mergeSize 的倍数时,实行步骤 [*]。这种情况下,如果剩余元素的数目比边界 middle 大,就要在大小为 MergeSize 的序列和剩余元素之间再进行一次排序。
过程 BottomUpSort
输入 n 个元素的数组 A[1...n]
输出 按非降序排列的数组 A[1...n]
算法描述
mergeSize ← 1
while mergeSize < n
low ← 0; middle ← low + mergeSize - 1; high ← low + mergeSize × 2 - 1
while high < n
Merge(A, low, middle, high)
low ← high + 1
end while
if middle < n then Merge(A, low, middle, n - 1) ← 步骤 [*]
mergeSize ← mergeSize × 2
end while
算法中用到的 Merge 方法,可以参考:算法之 分治 - 合并排序-合并两个已排序的表
此算法的 Java 实现如下所示:
public static void buttomUpSort(int[] array)
{
int arrayLength = array.length;
int mergeSize = 1;
while (mergeSize < arrayLength)
{
int low = 0, middle = 0, high = 0;
while (low + mergeSize * 2 - 1 < arrayLength)
{
middle = low + mergeSize - 1;
high = low + mergeSize * 2 - 1;
merge(array, low, middle, high);
low = high + 1;
}
middle = low + mergeSize - 1;
if (middle < arrayLength - 1)
{
merge(array, low, middle, arrayLength - 1);
}
mergeSize *= 2;
}
}
分享到:
相关推荐
以下是对自底向上合并排序算法的详细步骤: 1. **初始化**:假设我们有一个包含n个元素的数组A。我们将数组视为n个长度为1的子数组,即每个元素本身就是一个有序的子数组。 2. **合并阶段**:从长度为1的子数组...
以下将详细讲解标题和描述中提到的五种排序算法:选择排序、插入排序、自顶向上合并排序、合并排序以及快速排序。 1. **选择排序(Selection Sort)** 选择排序是一种简单直观的排序算法,它的工作原理是每一次从待...
合并排序是一种基于分治策略的高效排序算法,其基本思想是将大问题分解为小问题来解决,最终再将小问题的结果合并成大问题的解。在这个C语言实现的合并排序中,主要涉及两个关键部分:一是如何将数组拆分为更小的...
- 可以进一步优化合并排序,例如使用自底向上的方法,减少递归开销,或者在合并过程中使用缓冲区,减少数据拷贝。 通过理解和实践这个C语言实现的合并排序算法,你可以增强对分治策略的理解,同时提升C语言编程...
此外,为了提高效率,还可以进行优化,如使用迭代而非递归实现,减少函数调用的开销,或者使用更高效的合并策略,比如自底向上的合并排序,避免重复的数组分割。 总的来说,合并排序是一种高效且稳定的排序算法,...
- 如果内存限制允许,可以使用自底向上的归并排序方法,避免递归带来的开销。 - 在合并过程中,可以使用“缓冲区”技术,减少不必要的内存分配和释放,提高效率。 归并排序的应用场景: - 数据量较大且对稳定性有...
在提供的"算法-理论基础- 排序- 归并排序(包含源程序).pdf"文件中,可能会包含以下内容: 1. 归并排序的详细步骤解释,包括伪代码或流程图。 2. 归并排序的源代码实现,可能是C++、Java、Python或其他编程语言。 ...
在实际编程中,还可以考虑其他优化策略,如使用自底向上的合并排序(先处理较小的子数组,减少不必要的合并操作),或者采用尾递归优化来减少栈空间的使用。这些方法可以在保持算法效率的同时,优化资源的利用。通过...
合并排序是一种高效的、基于分治思想的排序算法。在计算机科学中,排序是将一组无序的数据元素按照特定顺序进行排列的过程。合并排序由美国计算机科学家John W. Backus于1946年提出,其核心思想是将大问题分解为小...
// 自底向上的归并排序 void squareRootMergeSort(vector<int>& arr, int n) { int sqrt_n = sqrt(n); for (int block_size = sqrt_n; block_size > 1; block_size /= 2) { for (int l = 0; l ; l += block_size ...
一个简单的合并排序的算法的演示过程。还不错。。
1. 自底向上归并排序:为了避免递归带来的开销,可以采用自底向上的方法,从长度为1的子序列开始,逐步合并成更大的有序序列。 2. 插入排序优化:对于小规模的子序列,可以考虑使用插入排序,因为插入排序在小规模...
合并排序算法是一种高效的排序算法,基于“分治”策略,由计算机科学家John W. Hoare在1960年提出。这种算法将一个大问题分解为小问题来解决,然后将小问题的解合并,得到原问题的解。在排序过程中,合并排序将一个...
归并排序(Merge Sort)是一种基于分治策略的高效排序算法,它的主要思想是将大问题分解成小问题,然后逐个解决小问题,最后再将解决好的小问题合并成解决大问题的答案。这种算法在计算机科学中有着广泛的应用,尤其...
自底向上归并排序不同于传统的递归版本,它避免了递归带来的额外开销,而是通过一系列的合并操作逐步将数组排序。首先,它将数组分成两个子数组,然后不断将已排序的小数组合并成更大的有序数组,直至整个数组有序。...
自底向上的归并排序是一种高效的排序算法,它利用了分治的思想,通过逐步合并小的有序序列来构建大的有序序列。在C++中实现这种排序算法,首先需要理解其基本原理。 一、算法描述 自底向上的归并排序算法主要分为...
5. **优化与改进**:除了基本算法,还可能探讨了优化策略,如快速排序的三数取中法选择基准,或者归并排序的自底向上的实现等。 6. **实际应用**:讨论排序算法在实际问题中的应用,比如数据库索引、数据挖掘、机器...
文档还可能讨论了如何优化合并排序,例如使用自底向上的方法减少递归深度,或者在内存受限的情况下如何调整算法。 2. **Hebing.java**:这是一个Java源代码文件,很可能是实现了合并排序算法的程序。通过阅读和理解...
- 归并排序可以使用自底向上的方法减少递归开销。 - 插入排序在小规模或部分有序的数据上表现优秀,可以结合其他算法进行混合排序,如希尔排序。 7. **编程语言实现**: - 排序算法在各种编程语言中都有实现,如...
- **最长公共子序列**:用于比较两个序列的相似程度,采用自底向上的动态规划方法。 4. **图论算法**: - **深度优先搜索(DFS)**:通过递归访问邻接节点,用于遍历或搜索图。 - **广度优先搜索(BFS)**:使用...