合并排序流程说明(自上而下,自下而上)

时间:2017-09-07 09:52:27

标签: c sorting mergesort

元素的合并排序处理步骤是什么: 20 47 15 8 9 4 40 30 12 17

我遇到过这个......

  

Pass1: | 20 47 | | 8 15 | | 4 9 | | 30 40 | | 12 17 |

     

Pass2: | 8 15 20 47 | | 4 9 30 40 | | 12 17 |

现在混淆的是Pass3和Pass4会是什么? (在Pass3中结合四边形或四边形+四边形)也是这种自上而下或自下而上的方法吗?

1 个答案:

答案 0 :(得分:2)

这些是自下而上合并排序的传递。 10个元素的数组被视为10个子数组,每个子元素包含1个元素,因为每个子数组只有1个元素。有n-1个合并操作(n / 2 + n / 4 + n / 8 + ...)。

 20 47 15  8  9  4 40 30 12 17    initial array 
|20|47|15| 8| 9| 4|40|30|12|17|   consider as 10 sub arrays of size 1
|20 47| 8 15| 4  9|30 40|12 17|   pass 1, 5 merges
| 8 15 20 47| 4  9 30 40|12 17|   pass 2, 2 merges
| 4  8  9 15 20 30 40 47|12 17|   pass 3, 1 merge
| 4  8  9 12 15 17 20 30 40 47|   pass 4, 1 merge

维基文章:

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation

请注意,虽然大多数课堂类型合并排序是自上而下的,但大多数实际库使用自下而上合并排序的一些变体。

这将是自上而下合并排序的操作顺序,它是深度优先,左边第一个。假设使用索引来拆分子阵列的优化自顶向下合并排序,由于子阵列的递归拆分,生成n-1对索引并将其存储在堆栈中,对应于与a发生的n-1合并操作典型的2路合并排序。请注意,合并不会开始,直到通过递归拆分创建两个大小为1的子数组的第一个实例。然后拆分和合并继续向上和向上调用堆栈,深度优先,先离开。

对于此示例中的10个元素,有10-1 = 9个拆分和合并操作。

 20 47 15  8  9  4 40 30 12 17 
|20 47 15  8  9| 4 40 30 12 17|  lvl 0 split
|20 47|15  8  9|                 lvl 1 split
|20|47|                          lvl 2 split
|20|                             lvl 3 size == 1
   |47|                          lvl 3 size == 1
|20 47|                          lvl 2 merge
      |15| 8  9|                 lvl 2 split
      |15|                       lvl 3 size == 1
         | 8| 9|                 lvl 3 split
         | 8|                    lvl 4 size == 1
            | 9|                 lvl 4 size == 1
         | 8  9|                 lvl 3 merge
      | 8  9 15|                 lvl 2 merge
| 8  9 15 20 47|                 lvl 1 merge
               | 4 40|30 12 17|  lvl 1 split
               | 4|40|           lvl 2 split
               | 4|              lvl 3 size == 1
                  |40|           lvl 3 size == 1
               | 4 40|           lvl 2 merge
                     |30|12 17|  lvl 2 split
                     |30|        lvl 3 size == 1
                        |12|17|  lvl 3 split
                        |12|     lvl 4 size == 1
                           |17|  lvl 4 size == 1
                        |12 17|  lvl 3 merge
                     |12 17 30|  lvl 2 merge
               | 4 12 17 30 40|  lvl 1 merge
| 4  8  9 12 15 17 20 30 40 47|  lvl 0 merge

自下而上合并排序通过将n个元素的数组视为每个1个元素的n个子数组来跳过所有递归拆分,并立即启动合并过程,通过迭代生成索引。对于大型数组,大部分时间用于合并,自上而下和自下而上都是相同的,在这种情况下,自顶向下并不比自下而上慢,但大多数库将实现自下而上合并的一些变化排序类似std :: stable_sort。