Fighting-算法-桶排序

"""
桶排序基本思想:
    将待排序集合中处于同一个'范围'的元素存入同一个桶中,根据划分范围和映射规则把集合拆分成多个桶,
    对每个桶中的元素进行排序,则所有桶中元素构成的集合是有序的。

计数排序与桶排序区别:
    计数排序:申请的额外空间跨度从最小值到最大值,若待排序集合中元素不是依次递增,则空间浪费。
    桶排序 :在最小值到最大值之间的固定区域范围申请空间,减少了元素值不连续情况下的空间浪费。

排序过程:
    1、根据待排序集合中元素最大值和最小值的差值范围和映射规则,确定申请的桶个数;
        映射规则:集合元素到桶的映射规则。
    2、遍历待排序集合,将集合中的元素移动到对应的桶中;
    3、对每一个桶中元素进行排序(桶中元素进行排序时,可以自主选择合适的排序算法),
       并移动到已排序集合(原始的待排序集合)中。


"""
import math


# 桶中元素采用插入排序
def insert_sort(nums):
    size = len(nums)
    for i in range(1, size):
        temp = nums[i]
        j = i - 1
        while j >= 0 and temp < nums[j]:
            nums[j+1] = nums[j]
            j = j - 1
            nums[j+1] = temp
    return nums


def bucket_sort(nums, bucket_size=5):
    """
    :param nums: 待排序集合
    :param bucket_size: 分配桶数--默认设置为5
    :return:
    """
    nums_len = len(nums)
    if nums_len is None:
        print('You don\'t have any elements in array!')

    min_value = nums[0]
    max_value = nums[0]

    # For finding minimum and maximum values
    for i in range(0, nums_len):
        if nums[i] < min_value:
            min_value = nums[i]
        elif nums[i] > max_value:
            max_value = nums[i]

    # Initialize buckets  math.floor()返回数字的下舍整数(向下取整)。
    bucket_count = math.floor((max_value - min_value) / bucket_size) + 1
    buckets = []
    for i in range(0, bucket_count):
        buckets.append([])

    # For putting values in buckets
    for i in range(0, nums_len):
        buckets[math.floor((nums[i] - min_value) / bucket_size)].append(nums[i])

    # Sort buckets and place back into input array
    sorted_arr = []
    for i in range(0, len(buckets)):
        insert_sort(buckets[i])
        for j in range(0, len(buckets[i])):
            sorted_arr.append(buckets[i][j])

    return sorted_arr


if __name__ == '__main__':
    sortedArray = bucket_sort([12, 23, 4, 5, 3, 2, 12, 81, 56, 95])
    print(sortedArray)
点赞