我合并两个排序数组有什么问题?

时间:2012-02-14 01:19:50

标签: java arrays merge

void sort(int a[], int b[], int m, int n)
    {
        int e = m + n;
        while(m >=0 && n >=0)
        {
            if(a[m] > b[n])
            {
                a[e] = a[m];
                m--;
                e--;
            }
            else if(a[e] < b[n])
            {
                a[e] = b[n];
                n--;
                e--;
            }
            else
            {
                a[e] = b[n];
                e--;
                n--;
                m--;
            }
        }
    }

public static void main(String[] args) {
        SortSorted obj = new SortSorted();
        int a[] = new int [6];
        int b[] = new int [3];
        a[0] = 1;
        a[1] = 2;
        a[2] = 3;
        b[0] = 2;
        b[1] = 7;
        b[2] = 8;
        obj.sort(a,b, 2, 2);
    }

在输入和不添加第三个其他条件的情况下,我将输出设为1 2 3 7 8 0而不是1 2 2 3 7 8

2 个答案:

答案 0 :(得分:1)

您开始e太低,应该是m + n + 1

考虑一下,对于两个三元素阵列,mn都是两个。这意味着你将从m + n开始四,而六元素结果,你应该从五开始。

这是一个相对简单的逐个错误。

您还可以通过简单地忽略相等来修复因等值而丢失值的其他问题。如果a大于或等于,则选择b,否则请选择a

你的循环延续逻辑是错误的,如果你先耗尽a = {2, 2, 3},你会看到它(使用b = {1, 7, 8}a看看我的意思)。只有在b#include <stdio.h> void sort (int a[], int b[], int m, int n) { // Start at correct offset for target array. int e = m + n + 1; // Until one list empty, choose the correct value. while (m >= 0 && n >= 0) if (a[m] >= b[n]) a[e--] = a[m--]; else a[e--] = b[n--]; // If b was empty, just transfer a. while (m >= 0) a[e--] = a[m--]; // If a was empty, just transfer b. while (n >= 0) a[e--] = b[n--]; } 都有剩余元素时才会继续。你应该继续 中剩下的元素。

您可以通过将该循环保持原样来修复此问题,但添加另外两个循环(其中只有一个实际上会执行任何操作)以耗尽其他列表。

作为支持,我提供了以下C代码(因为我比Java更快,但排序例程本身应该完全相同):

int main(void) {
    int a[6] = {2,2,3};
    int b[] = {1,7,8};
    sort (a, b, 2, 2);
    printf ("%d %d %d %d %d %d\n", a[0], a[1], a[2], a[3], a[4], a[5]);
    return 0;
}

还有一些测试代码:

1 2 2 3 7 8

这个输出是:

class Test {
    static void sort (int a[], int b[], int m, int n) {
        // Start at correct offset for target array.

        int e = m + n + 1;

        // Until one list empty, choose the correct value.

        while (m >= 0 && n >= 0)
            if (a[m] >= b[n])
                a[e--] = a[m--];
            else
                a[e--] = b[n--];

        // If b was empty, just transfer a.

        while (m >= 0)
            a[e--] = a[m--];

        // If a was empty, just transfer b.

        while (n >= 0)
            a[e--] = b[n--];
    }

正如所料。


等效的Java代码:

    static public void main(String[] args) {
        int a[] = new int[6];
        a[0] = 2; a[1] = 2; a[2] = 3;
        int b[] = new int[3];
        b[0] = 1; b[1] = 7; b[2] = 8;
        sort (a, b, 2, 2);
        for (int i = 0; i < 6; i++)
            System.out.println (a[i]);
    }
}  

及其测试套件:

a

事实上,既然你正在写while (m >= 0),你实际上可以忽略那个中间循环({{1}})。那是因为,在那种情况下,你只是将元素转移给自己。

我会保留它,因为如果您正在写入的数组不是就位变得很重要,但是如果您希望适合您的特定情况,则可以将其删除。

答案 1 :(得分:0)

这是你的其他陈述。 a和b中的元素是相同的,所以你应该插入两个元素,顺序无关紧要。相反,您只需插入b中的值。或者您可以放弃第二个条件并将其更改如下:

void sort(int a[], int b[], int m, int n)
    {
        int e = m + n + 1;
        while(m >=0 && n >=0)
        {
            if(a[m] > b[n])
            {
                a[e] = a[m];
                m--;
                e--;
            }
            else 
            {
                a[e] = b[n];
                n--;
                e--;
            }

        }
    }