Пример #1
0
def three_way_partition(a_list: list, from_: int, to_: int) -> Tuple[int, int]:
    """
    tree way partition that split the array to the tree parts
    lesser, equal and greater than the partitioning element
    :param a_list: list to partition
    :param from_: partition from here
    :param to_: partition to here
    :return: lt and gt separators
    """
    v = a_list[from_]
    i = from_
    lt = from_
    gt = to_

    while i <= gt:
        if a_list[i] < v:
            swap(a_list, i, lt)
            i += 1
            lt += 1
        elif a_list[i] > v:
            swap(a_list, i, gt)
            gt -= 1
        else:
            i += 1

    return lt, gt
Пример #2
0
def three_way_sort(a_list, low, hi):
    """
    recursive implementation of quick sort with three way partitioning
    :param a_list: a list to sort
    :param low: sort from this index
    :param hi: sort to this index
    """
    if hi <= low:
        return
    lt = low
    gt = hi
    v = a_list[low]
    i = low
    while i <= gt:

        if a_list[i] < v:
            swap(a_list, lt, i)
            lt += 1
            i += 1
        elif a_list[i] > v:
            swap(a_list, i, gt)
            gt -= 1
        else:
            i += 1

    three_way_sort(a_list, low, lt -1)
    three_way_sort(a_list, gt + 1, hi)
Пример #3
0
def partition(a_list: list, low: int, hi: int) -> int:
    """
    function to partition a list on the first element in such a way that
    all elements on the left of the array are lower then the partitioning element
    and everything to the right is higher
    :param a_list: a list to partition
    :param low: partition from this index
    :param hi: partition to this index
    :return: final position of the partitioning element
    """
    i = low + 1
    j = hi

    while i <= j:

        while less(a_list[low], a_list[j]):
            j -= 1
            if j <= low:
                break

        while less(a_list[i], a_list[low]):
            i += 1
            if i >= hi:
                break

        if i >= j:
            break
        swap(a_list, i, j)

    swap(a_list, low, j)
    return j
Пример #4
0
 def swim(self, index: int):
     """
     swim element at the given index to fix heap order
     :param index: index of element to swim
     """
     while index > 1 and self.compare(self.data[index], self.data[index // 2]):
         swap(self.data, index, index // 2)
         index //= 2
Пример #5
0
def knuth_shuffle(a_list: list):
    """
    performs inplace knuth shuffle
    produces uniformly random permutation of the list
    complexity O(N)
    :param a_list: list to shuffle
    """
    for i in range(len(a_list)):
        j = randint(0, i)
        swap(a_list, i, j)
Пример #6
0
def heap_sort(a_list: list):
    """
    performs in place heap sort using principles of binary heap
    complexity O(N log N)
    :param a_list: a list to sort
    """
    for i in range(len(a_list) // 2, -1, -1):
        sink(a_list, i, len(a_list) - 1)
    for i in range(len(a_list)):
        swap(a_list, 0, len(a_list) - i - 1)
        sink(a_list, 0, len(a_list) - i - 2)
Пример #7
0
 def remove(self) -> Any:
     """
     remove smallest element from the heap
     complexity O(log N)
     :return: smallest element
     """
     data = self.data[1]
     swap(self.data, 1, self.current_size)
     self.data[self.current_size] = None
     self.current_size -= 1
     self.sink(1)
     return data
Пример #8
0
def insertion_sort(a_list: list, h: int = 1):
    """
    performs inplace insertion sort on a_list
    Goes through the whole list and moves each element to the left until its in the correct place.
    complexity 0(N^2) ...~1/4 N^2
    :param a_list: a_list to sort
    :param h length of exchanges
    """
    list_len = len(a_list)
    for i in range(list_len):
        j = i
        while j >= h and less(a_list[j], a_list[j-h]):
            swap(a_list, j, j-h)
            j -= h
Пример #9
0
def selection_sort(a_list: list):
    """
    performs inplace selection sort on a_list.
    The function searches for the smallest element in the list and moves it the the beginning of the list.
    Then it searches for the smallest element in the reminder of the list (excluding the first element)
    and moves it to the second position in the list and so on.
    complexity O(N^2) ...~1/2 N^2

    :param a_list: list to sort
    """
    list_length = len(a_list)
    for i in range(list_length):
        min_index = i
        for j in range(i, list_length):
            if less(a_list[j], a_list[min_index]):
                min_index = j
        swap(a_list, i, min_index)
Пример #10
0
    def sink(self, index: int):
        """
        sink element at the given index to fix heap order
        :param index: index of element to sink
        """
        while 2 * index <= self.current_size:
            if self.current_size < 2 * index + 1:
                _child = 2 * index
            elif self.compare(self.data[2 * index], self.data[2 * index + 1]):
                _child = 2 * index
            else:
                _child = 2 * index + 1

            if self.compare(self.data[_child], self.data[index]):
                swap(self.data, _child, index)
                index = _child
            else:
                break
Пример #11
0
def sink(a_list: list, k: int, n: int):
    """
    sink operation for heap sort
    :param a_list: a list in which to perform the sink
    :param k: sink element on this index
    :param n: sink only up to this index
    """
    while (k + 1) * 2 <= n + 1:
        left_child = 2 * (k + 1) - 1
        right_child = min(2 * (k + 1), n)

        if a_list[left_child] < a_list[right_child]:
            bigger_child = right_child
        else:
            bigger_child = left_child

        if a_list[bigger_child] > a_list[k]:
            swap(a_list, k, bigger_child)
            k = bigger_child
        else:
            break