マージソート:小さなと課題

マージソート:小さなと課題

アレイにおいて、各要素の左側が加算要素値の現在の要素値よりも小さい、小型でアレイと呼ばれる
[2、3、4、1、5]:例を
左より2つのより小さな要素に2:なし
3左以下3つの要素より:2
4 4左側の要素よりも小さい:2,3
1左部材1よりも小さくなっている:いいえ
5よりも光素子から左に5:2、3、4、1
小及びsmall_sum = 2 + 2 + 3 + 2 + 3 + 4 + 1 = 17

ソリューション

マージソート特性バイナリアレイ、再帰ソート、補助アレイに置かれたとき、左右二つの配列のソートを使用する場合、そう右特定の要素番号があるが適切な数の右側に、左側よりも大きい場合単に累積和に、より大きい要素の数を乗算することにより要素、要素よりも確実に大きいです

アレイ[2、3、4、0、5、6、1、8]

次のようにマージソート、フォームへの再帰呼び出しは次のとおりです。

[2、3、4、0] [5、6、1、8]

[2、3] [4,0]、[5,6]、[1,8]

[2] [3] [4] [0] [5] [6] [1]〜[8]

補助アレイに配置されたときに右の後ろに他の数3、そう和+ = 2x1,2および3は昇順に存在しないので、再帰的特徴、最初のソートの2及び3は、左から右へ、3よりも小さくなっています。0,4及び4は、その後、0より大きい計算され、蓄積されていない、直接ソート。次いで、[2、3]を計算し、[0,4]、補助アレイに配置されたときに0の右側にある第二の左よりも大きい、2後ろに、0よりも大きい2、大きなに小さいためで残され番号は0よりも小さく、それ直接補助アレイ0,4へのポインタ、24より小さく、ないさらなる数字4の背後にできないので、2に入れ、次いで2和、和+ = 2×、とに蓄積補助アレイ、左点3未満、4 3、プラス累積和+ = 3×、と順番には、生成[0、2、3、4]。同様に右へ、及び右を降順にソートされているため、最終的には[0、2、3、4]およびソート[1,5,6,8]、左右1 0は、1よりも小さい0を比較ので、0よりも大きい後者の図は、+ 0 * 4直接累積和であることを、同様に他の要素;

コード

#include <stdio.h>

int helperArr[10];

int Merge(int arr[], int l, int mid, int r)
{
    int i = l;
    int p1 = l;
    int p2 = mid + 1;
    int sum = 0;
    while (p1 <= mid && p2 <= r) {
        sum += arr[p1] < arr[p2] ? arr[p1] * (r - p2 + 1) : 0;
        helperArr[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
    }
    while (p1 <= mid) {
        helperArr[i++] = arr[p1++];
    }
    while (p2 <= r) {
        helperArr[i++] = arr[p2++];
    }

    for (; l <= r; l++) {
        arr[l] = helperArr[l];
    }
    return sum;
}

int MergeSort(int arr[], int l, int r)
{
    if (l == r) {
        return 0;
    }
    int mid = l + ((r - l) >> 1); // =(l+r)/2 因为l+r有可能会溢出,所以改成减法的方式
    return MergeSort(arr, l, mid) + MergeSort(arr, mid + 1, r) + Merge(arr, l, mid, r);
}

int SmallSum(int arr[], int size)
{
    if (arr == NULL || size < 2) {
        return 0;
    }
    return MergeSort(arr, 0, size - 1);
}

void PrintArr(int arr[], int size)
{
    for (int i = 0; i < size; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\r\n");
}

int main()
{
    int arr[10] = {6, 0, 5, 3, 15, 21, 13, 9, 12, 8};
    PrintArr(arr, 10);
    int ret = SmallSum(arr, 10);
    PrintArr(arr, 10);
    printf("小和是:%d", ret);
    return 0;
}

おすすめ

転載: www.cnblogs.com/causewang/p/12064308.html