算法分析—计数排序(一种有趣的排序方法)

以前自己的博客总是零零散散,学习的东西也有记录,但是没有归纳到一块儿,后来也就慢慢丢了。所以打算定期花点时间,把学习的东西整理一下,以便日后查阅。

基本思想

计数排序是一种有趣又扯淡的排序方法。

我们有已知数组A,需要将A中的元素排序(默认从小到大);
第一步:我们需要一个辅助数组B,B中任意元素有该特点:下标表示A中某元素的值,B中的值表示该元素在A中出现得到次数。即 B[i]=i在A中出现的次数
第二步:循环输出B数组,输出规则为:当某元素a(下标为b)的值非零时,输出a个b;

该排序方法其实利用了数组下标的递增性进行排序,但是这样的方法有很大局限性。首先,值需要表示为下标,则只能用于整数的排序,其次,如果A中的值稀疏且巨大,则B数组的空间也会有很大浪费。如:A中数为1000000,则B数组长度至少要超过该值。

算法实现

首先是一个简易的生成指定个随机数的算法,文件命名data.py:

import random

# 生成num位随机数
def get_data(num):
    arr = []
    for i in range(0, num):
        arr.append(random.randint(0, 99))
    return arr

下面是用Python完成的计数排序算法:

import data

A = data.get_data(1000)

def counting_sort (arr):

    # 确定最大值(用于确定数组B的长度)
    max = -10000
    for i in arr:
        if i > max:
            max = i

    # 生成最大值位的数组B,元素值初始化为0
    B = [0] * (max + 1)

    # 用数组B记录元素在A中出现的次数
    for i in arr:
        B[i] += 1

    # 循环展开B
    arr = []
    index = 0
    for i in B:
        if i != 0:
           p = i
           while p >= 0:
               arr.append(index)
               p -= 1
        index += 1
    return arr


print(counting_sort(A))

复杂度分析

该算法我们可以看到主要的时间花费应该是在展开B数组获取排序后的值时,首先我们循环了B数组的长度次,即最大值。然后在找到非零值时又进行了循环确定元素出现的次数,该循环总和为A的长度。
所以T(n) = O(n+k),n为元素个数,k为最大值。

你可能感兴趣的:(算法分析)