Bottom up merge sort sorts the array without using recursion. It is 10% slower than the top down (recursive) mergesort. The idea is to start sorting the array elements from the start in groups of 2, 4, 8, 16, and so on (powers of two). So that the effect is the same as the recursive algorithm.

Here is a trace for sorting numbers 13,12, ..., 1

Source:

[11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

start = 0 mid = 0 end = 1

[10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[10, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1]

start = 2 mid = 2 end = 3

[10, 11, 8, 9, 0, 0, 0, 0, 0, 0, 0]

[10, 11, 8, 9, 7, 6, 5, 4, 3, 2, 1]

start = 4 mid = 4 end = 5

[10, 11, 8, 9, 6, 7, 0, 0, 0, 0, 0]

[10, 11, 8, 9, 6, 7, 5, 4, 3, 2, 1]

start = 6 mid = 6 end = 7

[10, 11, 8, 9, 6, 7, 4, 5, 0, 0, 0]

[10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1]

start = 8 mid = 8 end = 9

[10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0]

[10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1]

start = 0 mid = 1 end = 3

[8, 9, 10, 11, 6, 7, 4, 5, 2, 3, 0]

[8, 9, 10, 11, 6, 7, 4, 5, 2, 3, 1]

start = 4 mid = 5 end = 7

[8, 9, 10, 11, 4, 5, 6, 7, 2, 3, 0]

[8, 9, 10, 11, 4, 5, 6, 7, 2, 3, 1]

start = 8 mid = 9 end = 10

[8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3]

[8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3]

start = 0 mid = 3 end = 7

[4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3]

[4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3]

start = 0 mid = 7 end = 10

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Here is a trace for sorting numbers 13,12, ..., 1

Source:

import java.util.Arrays; public class BottomUpMergeSort { public static void merge(int[] orig, int[] aux, int start, int mid, int end) { int i, j, z = start; if(orig[mid] <= orig[mid+1])return; for(i=start, j = mid+1; i!=mid+1 || j!=end+1;){ if(i==mid+1) while(j!=end+1){ aux[z++] = orig[j++]; } else if(j==end+1) while(i!=mid+1){ aux[z++] = orig[i++]; } else if(orig[i]<=orig[j]) aux[z++] = orig[i++]; else aux[z++] = orig[j++]; } System.out.println(Arrays.toString(orig)); System.out.println("start = "+start+" mid = "+mid+" end = "+end); System.out.println(Arrays.toString(aux)+"\n"); System.arraycopy(aux, start, orig, start, end-start+1); } public static void sort(int[] orig, int[] aux, int start, int end) { int N = orig.length; for (int sz = 1; sz < N; sz *= 2) { for (int lo = 0;lo < N - sz; lo += sz + sz) { merge(orig, aux, lo, lo + sz - 1, Math.min(lo + sz + sz - 1, N-1)); } } } public static void main(String[] args) { int array[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; int aux[] = new int[array.length]; sort(array, aux, 0, array.length - 1); } }lo < N - sztakes care to see that the mid value falls beforeend. lo < N - sz lo + sz < N lo + sz - 1 < N - 1 mid < N - 1 Math.min() takes care to see that end does not extend beyond the last index.

**Output:**[11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

start = 0 mid = 0 end = 1

[10, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0]

[10, 11, 9, 8, 7, 6, 5, 4, 3, 2, 1]

start = 2 mid = 2 end = 3

[10, 11, 8, 9, 0, 0, 0, 0, 0, 0, 0]

[10, 11, 8, 9, 7, 6, 5, 4, 3, 2, 1]

start = 4 mid = 4 end = 5

[10, 11, 8, 9, 6, 7, 0, 0, 0, 0, 0]

[10, 11, 8, 9, 6, 7, 5, 4, 3, 2, 1]

start = 6 mid = 6 end = 7

[10, 11, 8, 9, 6, 7, 4, 5, 0, 0, 0]

[10, 11, 8, 9, 6, 7, 4, 5, 3, 2, 1]

start = 8 mid = 8 end = 9

[10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0]

[10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 1]

start = 0 mid = 1 end = 3

[8, 9, 10, 11, 6, 7, 4, 5, 2, 3, 0]

[8, 9, 10, 11, 6, 7, 4, 5, 2, 3, 1]

start = 4 mid = 5 end = 7

[8, 9, 10, 11, 4, 5, 6, 7, 2, 3, 0]

[8, 9, 10, 11, 4, 5, 6, 7, 2, 3, 1]

start = 8 mid = 9 end = 10

[8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3]

[8, 9, 10, 11, 4, 5, 6, 7, 1, 2, 3]

start = 0 mid = 3 end = 7

[4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3]

[4, 5, 6, 7, 8, 9, 10, 11, 1, 2, 3]

start = 0 mid = 7 end = 10

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

## No comments:

## Post a Comment