线性时间排序 Sorting in linear time O(n)

时间:2021-08-04 07:43:05

 Sorting In Linear Time 


之前尝试过很多的排序算法, 都是基于比较的排序算法(base on comparing)

Collection of algorithm for sorting (part one)

http://blog.csdn.net/cinmyheart/article/details/39268783

Collection of algorithm for sorting (part two)

http://blog.csdn.net/cinmyheart/article/details/39396651

Collection of algorithm for sorting (part three)

http://blog.csdn.net/cinmyheart/article/details/39413037


------------------------------------------------------------------------------------------------------------------------------------

前面一些基于比较的排序算法的时间复杂度:


线性时间排序 Sorting in linear time O(n)


时间复杂度为O(n)的Counting Sort 计数排序


所有的排序算法都会在这个O(n)面前黯然失色 ...


这里给出两个语言实现的版本


C语言实现:

/*********************************************************
 Code writer : EOF
 Code date   : 2014.01.11
 Code file   : counting_sort.c
 e-mail      : jasonleaster@gmail.com

 Code description:
   Here is a implementation for counting sort.

   If you find something wrong with my code, please touch
me by e-mail.

*********************************************************/
#include <stdio.h>
#include <stdlib.h>

int counting_sort(int *num,int array_size)
{
    if(!num)
    {
        return -1;
    }

    int *p_tmp = (int*)malloc(sizeof(int)*array_size);

    if(!p_tmp)
    {
         printf("malloc failed %d\n",__LINE__);
         return 0;
    }

    int i = 0;
    int max_value = 0;
    for(i = 0; i < array_size; i++)
    {
        max_value = max_value > num[i] ?
                    max_value : num[i];

        p_tmp[i] = num[i];
    }

    int counter_size = max_value + 1;

    int *p_counter = (int*)malloc(sizeof(int)*counter_size);

    if(!p_counter)
    {
         printf("malloc failed %d\n",__LINE__);
         return 0;
    }

    //initialization
    for(i = 0; i < counter_size; i++)
    {
        p_counter[i] = 0;
    }

    //counting
    for(i = 0; i < array_size; i++)
    {
        p_counter[num[i]] += 1;
    }

    //caculating
    for(i = 1; i < counter_size; i++)
    {
        p_counter[i] += p_counter[i-1];
    }

    //output from bigger element to smaller element
    for(i = array_size -1;i >= 0; i--)
    {
        num[p_counter[p_tmp[i]] - 1] = p_tmp[i];

        p_counter[p_tmp[i]] -= 1;
    }

    free(p_counter);
    free(p_tmp);

    return 0;
}

int main()
{
    int array[] = {1,3,4,3,2,7,4,0};
    int size_array = sizeof(array)/sizeof(array[0]);

    int i = 0;
    printf("Before sorting:array[] = \n");
    for(i = 0; i < size_array; i++)
    {
        printf("\t%d",array[i]);
    }

    printf("\n");
    counting_sort(array,size_array);

    printf("After sorting:array[] = \n");
    for(i = 0; i < size_array; i++)
    {
        printf("\t%d",array[i]);
    }
    printf("\n");

    return 0;
}

线性时间排序 Sorting in linear time O(n)


Python实现:

"""
 Code writer : EOF
 Code date   : 2014.01.11
 Code file   : counting_sort.py
 e-mail      : jasonleaster@gmail.com

 Code description:
   Here is a implementation for counting sort.

   If you find something wrong with my code, please touch
me by e-mail.
"""

def counting_sort(array) :
    array_size = len(array)

    max_value = 0

    for i in range(0,array_size) :
        if max_value < array[i] :
           max_value = array[i]

    buf_size = max_value + 1

    buf  = [0] * buf_size
    ret  = [0] * array_size

    for i in range(0, array_size) :
        buf[array[i]] += 1
     
    for i in range(1, buf_size) :
        buf[i] += buf[i-1]

    for i in range(array_size - 1, -1, -1) :
        ret[buf[array[i]] - 1] = array[i]
        buf[array[i]] -= 1

    return ret

array = [1,3,4,3,2,7,4,0]

print "Befor sorting" ,array

sorted_ary = counting_sort(array)

print "After sorting", sorted_ary

线性时间排序 Sorting in linear time O(n)



update : 2015.01.12

之前的代码有误,现已更正

计数排序的精髓就在于index索引.

ret[buf[array[i]] - 1] = array[i]





既不是向东,也不是向西,而是指向内心

线性时间排序 Sorting in linear time O(n)