"""
Bucketsort implementation using linked lists

Copyright 2026, University of Freiburg.

Philipp Schneider <philipp.schneider@cs.uni-freiburg.de>
Marc Fuchs <marc.fuchs@cs.uni-freiburg.de>
"""

import Queue

from ListElement import ListElement


def bucket_sort(array, k, key=lambda x: x):
    '''
    Implements the bucket sort algorithm to sort
        data elements using a key function to
        assign sorting keys to data elements

    Args:
        array: array of data elements
        k: largest key
        key: a function mapping data elements to values
        in range(k+1) (idendity function as default)

    >>> array = []
    >>> bucket_sort(array, 10)
    >>> str(array)
    '[]'
    >>> array = [10-i for i in range(10)]
    >>> bucket_sort(array, 10)
    >>> str(array)
    '[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]'
    >>> array = [4, 6, 1, 2, 2, 3, 8, 9, 0]
    >>> bucket_sort(array, 10)
    >>> str(array)
    '[0, 1, 2, 2, 3, 4, 6, 8, 9]'
    '''

    bucket = [Queue.Queue() for _ in range(k + 1)]

    # put dataelements into according buckets
    for i in range(len(array)):
        bucket[key(array[i])].enqueue(ListElement(array[i]))

    # fill keys from buckets back into array
    i = 0
    for j in range(k+1):
        while not bucket[j].is_empty():
            array[i] = bucket[j].dequeue().get_key()
            i += 1
