一种将降序变为升序的算法,但为什么正确呢?

计算科学 排序
2021-12-13 20:38:15

我想知道为什么下面的这个算法效果很好?许多人赞赏!

任务:

的数组中的所有元素都按降序排列:,我们需要将它们变成升序。n=2ma1>a2>...>an

算法:

的每一步1m

  1. 将每个相邻(奇数索引,偶数索引)对交换为升序,以便: a1a2,a3a4,...,an1an
  2. 将所有具有奇数索引的元素移动到具有偶数索引的元素的前面,因此变为:a1,a2,a3,a4,...,an1,ana1,a3,...,an1,a2,a4,...,an

例子:

对每一步后的结果进行排序n=8

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

代码:

#include <stdlib.h>

void swap(int *arr, int i, int j)
{
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

void magic_sort(int *arr, int *result, int n)
{
    int half = n >> 1;
    int i;

    /* Swap adjacent (odd index, even index) pair into ascending order */
    for (i = 1; i <= n; i += 2)
    {
        if (arr[i] > arr[i + 1])swap(arr, i, i + 1);
    }

    /* Move all elements with odd index to front half */
    for (i = 1; i <= n; i += 2)
    {
        result[(i + 1) / 2] = arr[i];
    }

    /* Move all elements with even index to tail half */
    for (i = 2; i <= n; i += 2)
    {
        result[half + i / 2] = arr[i];
    }

    for (i = 1; i <= n; i++)
    {
        arr[i] = result[i];
    }
}

int main()
{
    int m = 3;
    int n = 1 << m;
    int *arr = (int *)malloc(sizeof(*arr) * (n + 1));
    int *result = (int *)malloc(sizeof(*arr) * (n + 1));
    int step, i;

    printf("[%d] ", 0);

    for (i = 1; i <= n; i++)
    {
        arr[i] = n + 1 - i;

        printf("%d ", arr[i]);
    }

    printf("\n");

    for (step = 0; step < m; step++)
    {
        magic_sort(arr, result, n);

        printf("[%d] ", step + 1);

        for (i = 1; i <= n; i++)
        {
            printf("%d ", arr[i]);
        }

        printf("\n");
    }

    free(arr);
    free(result);

    return 0;
}
0个回答
没有发现任何回复~