Python basic sorting algorithm to achieve

bubble sort, merge sort, heap sort and quick sort

from functools import wraps
from time import time

import numpy as np

size = 100000
print('size = {}\n'.format(size))

def timing(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        a = np.random.randint(size, size=size)
        print('Function {} was called'.format(func.__name__))
        start = time()
        result = func(a)
        end = time()
        print('Elapsed time: {:.3f} s\n'.format(end-start))
        return result
    return wrapper

# bubble sort

@timing
def bubble_sort(arr: 'array') -> 'the sorted array':
    n = len(arr)
    for i in range(n - 1):
        for j in range(n - (i+1)):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

# merge sort

def merge(left, right):
    result = []
    i, j = 0, 0
    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])   
    return result

def merge_sort(arr):
    n = len(arr)
    if n <= 1:
        return arr
    middle = int(n/2)
    left = merge_sort(arr[:middle])
    right = merge_sort(arr[middle:])
    return merge(left, right)


def in_place_merge(arr, left, middle, right):
    i, j = left, middle+1
    while i <= middle and j <= right:
        if arr[i] <= arr[j]:
            i += 1
        else:
            temp = arr[j]
            arr[i+1:j+1] = arr[i:j]  # shift part of the array
            arr[i] = temp
            i += 1
            j += 1
            middle += 1 

def in_place_merge_sort(arr, left, right):
    if left < right:
        middle = int((left+right) / 2)
        in_place_merge_sort(arr, left, middle)
        in_place_merge_sort(arr, middle+1, right)
        in_place_merge(arr, left, middle, right)

# heap sort

def max_heapify(arr, node: 'in [0, ..., n-1]', heap_size):
    left = 2*node + 1
    right = left + 1
    largest = node
    if left <= heap_size-1 and arr[left] > arr[node]:
        largest = left
    if right <= heap_size-1 and arr[right] > arr[largest]:
        largest = right
    if largest != node:
        arr[node], arr[largest] = arr[largest], arr[node]
        max_heapify(arr, largest, heap_size)

def build_max_heap(arr):
    n = len(arr)
    for node in range(int(n/2)-1, -1, -1):
        max_heapify(arr, node, n)

def heap_sort(arr):
    build_max_heap(arr)
    heap_size = len(arr)
    for node in range(len(arr)-1, 0, -1):
        arr[0], arr[node] = arr[node], arr[0]
        heap_size -= 1
        max_heapify(arr, 0, heap_size)

# quick sort

import sys
sys.setrecursionlimit(size)

def partition(arr, left, right):
    pivot = arr[right]
    i = left - 1
    for j in range(left, right):
        if arr[j] <= pivot:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]    
    arr[i+2:right+1] = arr[i+1:right]
    arr[i+1] = pivot
    return i + 1

def quick_sort(arr, left, right):
    if left < right:
        p_index = partition(arr, left, right)
        quick_sort(arr, left, p_index-1)
        quick_sort(arr, p_index+1, right)


def randomized_partition(arr, left, right):
    index = np.random.randint(left, right)
    arr[index], arr[right] = arr[right], arr[index]
    # the only difference is above two lines
    pivot = arr[right]
    i = left - 1
    for j in range(left, right):
        if arr[j] <= pivot:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
    
    arr[i+2:right+1] = arr[i+1:right]
    arr[i+1] = pivot
    return i + 1

def randomized_quick_sort(arr, left, right):
    if left < right:
        p_index = randomized_partition(arr, left, right)
        quick_sort(arr, left, p_index-1)
        quick_sort(arr, p_index+1, right)   


bubble_sort()

def test(func, *args, **kwargs):
    a = np.random.randint(size, size=size)
    print('Function {} was called'.format(func.__name__))
    start = time()
    func(a, *args, **kwargs)
    end = time()
    print('Elapsed time: {:.3f} s\n'.format(end-start))

test(merge_sort)
test(in_place_merge_sort, left=0, right=size-1)
test(heap_sort)
test(quick_sort, left=0, right=size-1)
test(randomized_quick_sort, left=0, right=size-1)

Guess you like

Origin www.cnblogs.com/shiina922/p/11129822.html