如何在MergeSort中逐步打印出来

时间:2011-12-06 20:21:10

标签: java

我在打印MergeSort时遇到问题。我需要帮助打印出每个一步一步的过程,因为它正在对ArrayList进行排序。

以下示例来自InsertionSort,因为我在每次交换ArrayList中的两个元素时都会打印它:

11 79 60 45 START

11 79 60 45

11 60 79 45

11 45 60 79结束

有没有为MergeSort做这个,同时从头到尾显示整个数组(如上所述?)

代码:

import java.util.ArrayList;

public class Merge 
{
    public static void main (String [] args) 
    {
        Merge run = new Merge();
        run.test();
    }

    public void test ( )
    {
        ArrayList<Integer> numbers = new ArrayList<Integer>();
        for (int i = 0; i < 16; i++)
        {
            numbers.add(new Integer(1 + (int)(Math.random() * 100)));
        }
        printArray(numbers);
        mergeSort(numbers);
        printArray(numbers);
    }

    public void printArray (ArrayList<Integer> array)
    {
        System.out.println("\n\n");
        for (int i = 0; i < array.size(); i++)
        {
            System.out.printf("%-5d",array.get(i).intValue());
        }
        System.out.println("\n\n");
    }

    public void mergeSort (ArrayList<Integer> array) 
    {   
        int length = array.size();
        if (length < 2)
        {
            return;  // the array is already sorted in this case
        }
        // divide
        ArrayList<Integer> array1 = new ArrayList<Integer>(); 
        ArrayList<Integer> array2 = new ArrayList<Integer>(); 
        int i = 0;

        while (i < length/2)
        {
            array1.add(array.remove(0)); // move the first n/2 elements to array1
            i++;
        }
        while (!array.isEmpty())
        {
            array2.add(array.remove(0)); // move the rest to array2
        }

        mergeSort(array1);
        mergeSort(array2);
        merge(array1,array2,array); 
    }

    public void merge (ArrayList<Integer> array1, ArrayList<Integer> array2, ArrayList<Integer> array)
    {   
        while (!array1.isEmpty() && !array2.isEmpty())
        {
            if ((array1.get(0).compareTo(array2.get(0)) <= 0))
            {
                array.add(array1.remove(0));
            }
            else
            {
                array.add(array2.remove(0));
            }
        }
        while(!array1.isEmpty()) // move the remaining elements of array1
        {
            array.add(array1.remove(0));
        }
        while(!array2.isEmpty()) // move the remaining elements of array2
        {
            array.add(array2.remove(0));
        }
    }
}

3 个答案:

答案 0 :(得分:2)

如果你将一些偏移量传递给mergeSort,你可以将子阵列打印到你完成交换时缩进到完整数组中的位置,但是因为你只传递部分的如果阵列向下,您将无法以这种方式显示完整的阵列。但是,有一种更快的方法可以让你。

不是创建新数组并传递它们,而是传递数组和2个索引,即开始和结束点。因此,您对第一个说mergeSort(array, 0, n),然后对递归调用说mergeSort(array, 0, n/2)mergeSort(array, n/2, n)。你只在这些范围内进行拆分和合并。然后在合并时,可以打印出整个合并的数组。这将显示每次合并的步骤。在底层,它将显示1-1交换(如果它发生)。这是唯一的&#34;一步一步&#34;你可以在合并排序中看到。

答案 1 :(得分:1)

没有看到你的代码,很难确切知道,但我从这里抓住了一个Mergesort实现:http://www.vogella.de/articles/JavaAlgorithmsMergesort/article.html
我已将其更新为您想要的打印效果。

public class Mergesort 
{
    private int[] numbers;
    private int[] helper;

    private int number;

    public void sort(int[] values) 
    {
        this.numbers = values;
        number = values.length;
        this.helper = new int[number];

        System.out.println("START");

        mergesort(0, number - 1);

        System.out.println("END");
    }

    private void mergesort(int low, int high) 
    {
        // Check if low is smaller then high, if not then the array is sorted
        if (low < high) 
        {
            // Get the index of the element which is in the middle
            int middle = (low + high) / 2;
            // Sort the left side of the array
            mergesort(low, middle);
            // Sort the right side of the array
            mergesort(middle + 1, high);
            // Combine them both
            merge(low, middle, high);
        }
    }

    private void merge(int low, int middle, int high) 
    {

        // Copy both parts into the helper array
        for (int i = low; i <= high; i++) 
        {
            helper[i] = numbers[i];
        }

        int i = low;
        int j = middle + 1;
        int k = low;

        // Copy the smallest values from either the left or the right side back
        // to the original array
        while (i <= middle && j <= high) 
        {
            if (helper[i] <= helper[j]) 
            {
                numbers[k] = helper[i];
                i++;
            } 
            else 
            {
                numbers[k] = helper[j];
                j++;
            }
            k++;
        }

        // Copy the rest of the left side of the array into the target array
        while (i <= middle) 
        {
            numbers[k] = helper[i];
            k++;
            i++;
        }

    }

    private void printArray()
    {
        for(int x : numbers)
            System.out.print(x + " ");

        System.out.println(" ");
    }
}

如果您不想打印到控制台,可以将输出构建为输出的String,并在完成后将其返回。

答案 2 :(得分:1)

这是一个小的Merge排序算法程序。我复制了算法 http://en.wikipedia.org/wiki/Merge_sort。您可以将其作为JUnittest运行或运行main方法。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;

/**
 * Simple MergeSortTest
 */

public class MergeSortTest extends TestCase {


private static int FIRST_ENTRY = 0;

public static void main(String[] args) {
    MergeSortTest mergesorttest = new MergeSortTest();
    Integer [] unsortedInt = {1,38, 27, 110, 9, 82, 10, 100, 299, 13};
    List<Integer> unsorted = Arrays.asList(unsortedInt);
    List<Integer> sorted = mergesorttest.mergeSort(unsorted);
    System.out.println(sorted.toString());
}

public void testMergeSort() {
    Integer [] unsortedInt = {1,38, 27, 110, 9, 82, 10, 100, 299, 13};
    List<Integer> unsorted = Arrays.asList(unsortedInt);
    List<Integer> sorted = mergeSort(unsorted);
    assertEquals("[1, 9, 10, 13, 27, 38, 82, 100, 110, 299]", sorted.toString());
}

private List<Integer> mergeSort(List<Integer> list) {
    List<Integer> result;
    List<Integer> left = new ArrayList<Integer>();
    List<Integer> right = new ArrayList<Integer>();;
    int middle;
    int counter;
    if (list.size() <= 1) {
        return list;
    }
    middle = list.size() / 2;

    for (counter = 0; counter < middle; counter++)  {
        left.add(list.get(counter));
    }

    for (counter = middle; counter < list.size(); counter++)  {
        right.add(list.get(counter));
    }   

    left = mergeSort(left);
    right = mergeSort(right);
    result = merge(left, right);
    System.out.println(result);
    return result;
}

private List<Integer> merge(List<Integer> left, List<Integer> right) {
    List<Integer> result = new ArrayList<Integer>();
    while (!left.isEmpty() || !right.isEmpty()) {
        if (!left.isEmpty() && !right.isEmpty()) {
            if (left.get(FIRST_ENTRY) <= right.get(FIRST_ENTRY)) {
                handle(left, result);
            } else {
                handle(right, result);
            }
        } else if (!left.isEmpty()) {
            handle(left, result);
        } else if (!right.isEmpty()) {
            handle(right, result);
        }
    }
    return result;  
}

private void handle(List<Integer> list, List<Integer> result) {
    if (!list.isEmpty()) {
        result.add(list.get(FIRST_ENTRY));
        list.remove(FIRST_ENTRY);
    }
}

}