代码改变世界

归并排序

2017-12-19 13:46  woodzcl  阅读(184)  评论(0编辑  收藏  举报

印象中,当年我的老师是很强调归并算法的,处处涉及它。那时候年轻,不胜理解。今天,我把排序相关的内容温故一遍后,才有感同身受!!!

归并算法除了能达到最优秀的O(nlog2n)的时间复杂度外,它比快速算法强在于没有意外的情况(快速算法最快能达到O(nlogn)),除了要多提供一个同量的附加占用空间外,它真实没毛病了。对于如今的大内存计算机而言,它就是完美的啊。所以,以后的排序问题,我都打算用归并来解决了。

——————————————————————————————————————————————

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

void merge(int arr1[], int arr2[], int left, int mid, int right)

{

    int i = left, j = mid+1, k = left;

    while (i<=mid&&j<=right)

    {

        if (arr1[i]<=arr1[j])

        {

            arr2[k++] = arr1[i++];

        }

        else

        {

            arr2[k++] = arr1[j++];

        }

    }

    while (i<=mid)

    {

        arr2[k++] = arr1[i++];

    }

    while (j<=right)

    {

        arr2[k++] = arr1[j++];

    }

}

 

void mergepass(int arr1[], int arr2[], int length, int len)

{

    int i = 0;

   

    while (i+2*len<=length)

    {

        merge(arr1, arr2, i, i+len-1, i+2*len-1);

        i = i+2*len;

    }

    if (i+len<=length-1)

    {

        merge(arr1, arr2, i, i+len-1, length-1);

    }

    else

    {

        for (int j=i; j<length; j++)

        {

            arr2[j] = arr1[j];

        }

    }

}

 

void mergesort_iter(int arr[], int length)

{

    int *arr1 = (int*)malloc(length*sizeof(int));

    int len = 1;

    if (arr1)

    {

        while (len<length)

        {

            mergepass(arr, arr1, length, len);

            len *= 2;

            mergepass(arr1, arr, length, len);

            len *= 2;

        }

        free(arr1);

    }

}

 

void main()

{

    int arr[] = {88, 1, 7, 9, 2, 4,3, 7, 5, 22, 77, 56, 34, 23, 55, 66, 98, 89};

    int len = sizeof(arr)/sizeof(int);

   

    mergesort_iter(arr, len);

 

    for (int i=0; i<len; i++)

    {

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

    }

 

    printf("\n");

}   

// result

# ./sort
1 2 3 4 5 7 7 9 22 23 34 55 56 66 77 88 89 98

 

Finally:

时代在发展,思想得更新!