Использование стеков для Нерекурсивного слияния?

мой профессор поставил задачу, в которой мы должны использовать стеки (или очереди) для создания нерекурсивного слияния. Текущий код выглядит следующим образом:

 private static void sort(Comparable[] a, int[] index, int[] aux, int lo, int hi) {
    if (hi <= lo) return;
    int mid = lo + (hi - lo) / 2;

    sort(a, index, aux, lo, mid);
    sort(a, index, aux, mid + 1, hi);

    merge(a, index, aux, lo, mid, hi);

Я не уверен, как подойти к этой проблеме, и любая помощь будет оценена. Я знаю, что должен использовать цикл while для эмуляции рекурсии. Но как я могу разделить фактические значения? Кроме того, как я могу отслеживать середину секционированных значений?

Я действительно смущен проблемой. Любая помощь будет ценю!

1 ответов


самое главное-понять, как алгоритм работает. От Википедия:

концептуально сортировка слияния работает следующим образом:

разделить несортированный список на подсписки, каждый из которых содержит 1 элемент (а список из 1 элемента считается отсортированным). Многократно объединять подсписки в создавайте новые сортированные подсписки, пока не останется только 1 подсписка. Это будет сортировка список.

Mergesort animation

Решение 1: С очередью.


static int[] mergeSortQueue(int[] A) {
        Queue<int[]> queue = new LinkedList<int[]>();


        for (int i = 0; i < A.length; i++)
        {
            queue.add(new int[]{A[i]});
        }
        while (queue.size()>1)
        {
                int[] r = queue.poll();
                int[] l = queue.poll();
                int[] merged=merge(l, r);
                queue.add(merged);  
        }
        return queue.poll();


    }

графически,

mergesort_queue


решение 2: С двумя стеками


Это немного сложнее.

он в основном состоит из слияния элементов первого стека, вставки их во второй стек, пока только один остатки.

static int[] mergeSortStacks(int[] A) {
        Stack<int[]> stack = new Stack<int[]>();
        Stack<int[]> stack2 = new Stack<int[]>();

        for (int i = 0; i < A.length; i++)
        {
            stack.push(new int[]{A[i]});
        }
        while (stack.size()>1)
        {
            while (stack.size()>1)
            {

                int[] r = stack.pop();
                int[] l = stack.pop();
                int[] merged=merge(l, r);
                stack2.push(merged);
            }
            while (stack2.size()>1)
            {

                int[] r = stack2.pop();
                int[] l = stack2.pop();
                int[] merged=merge(l, r);
                stack.push(merged);
            }
        }
        return stack.isEmpty() ? stack2.pop() : stack.pop();


    }

графически,

enter image description here