合并矢量非常快

时间:2015-05-24 19:05:05

标签: c

我想非常快速地合并数字向量。我在一本书中发现合并两个大小为n1和n2的向量,与n1 + n2成比例时间。那么合并三个大小为n1,n2,n3的向量,确实有序吗?如果确实如此,为什么?

编辑: 是的,矢量是有序的,结果必须按订购。

1 个答案:

答案 0 :(得分:0)

Merging two sorted arrays in the generic case takes between the smaller of n1 and n2 and the sum n1+n2-1 comparisons and n1+n2 moves.

You can optimize special cases at very little cost, such as the cases where all values in one array are below all values in the other. Doing this significantly improves the performance of mergesort on sorted and reverse sorted arrays.

If one of the arrays is significantly smaller than the other, binary searching elements of the smaller array in the larger array will significantly lower the number of comparison and allow for block moving elements from the larger array to the destination.

Careful implementation of the merging code will avoid testing array boundaries unnecessarily.

Here is some code:

static void merge(int *dest, const int *a1, size_t n1, const int *a2, size_t n2) {
    if (n1 == 0 || n2 == 0 || a1[n1 - 1] <= a2[0]) {
        /* trivial cases and arrays in order */
        memcpy(dest, a1, n1 * sizeof(int));
        memcpy(dest + n1, a2, n2 * sizeof(int));
        return;
    }
    if (a2[n2 - 1] < a1[0]) {
        /* arrays should be swapped */
        memcpy(dest, a2, n2 * sizeof(int));
        memcpy(dest + n2, a1, n1 * sizeof(int));
        return;
    }
    /* general case */
    for (const int *e1 = a1 + n1, *e2 = a2 + n2;;) {
        if (*a1 <= *a2) {
            *dest++ = *a1++;
            if (a1 >= e1) {
                memcpy(dest, a2, (e2 - a2) * sizeof(int));
                break;
            }
        } else {
            *dest++ = *a2++;
            if (a2 >= e2) {
                memcpy(dest, a1, (e1 - a1) * sizeof(int));
                break;
            }
        }
    }
}