EdisonChendi
4/14/2018 - 1:06 PM

merge sort + merge n sorted list with variable length

merge sort + merge n sorted list with variable length

#coding:UTF-8

import math

def merge_sort(l):

    if len(l) <= 1:
        return l

    mid_idx = (len(l)-0)//2
    left = l[0:mid_idx]
    right = l[mid_idx:]

    sorted_left = merge_sort(left)
    sorted_right = merge_sort(right)

    return merge(sorted_left, sorted_right)

# def merge(left, right):

#     i = j = 0
#     len_left = len(left)
#     len_right = len(right)
#     merged = []

#     while i < len_left and j < len_right:
#         l = left[i]
#         r = right[j]
#         if l < r:
#             merged.append(l)
#             i += 1
#         else:
#             merged.append(r)
#             j += 1

#     if i == len_left:
#         merged.extend(right[j:])
#     if j == len_right:
#         merged.extend(left[i:])

#     return merged

# def merge(left, right):

#     iter_left = iter(left)
#     iter_right = iter(right)

#     l = next(iter_left)
#     r = next(iter_right)

#     merged = []

#     while True:
#         if l < r:
#             merged.append(l)
#             try:
#                 l = next(iter_left)
#             except StopIteration:
#                 merged.append(r)
#                 merged.extend(iter_right)
#                 return merged
#         else:
#             merged.append(r)
#             try:
#                 r = next(iter_right)
#             except StopIteration:
#                 merged.append(l)
#                 merged.extend(iter_left)
#                 return merged

def merge(*n_sorted_lists):
    # assume every list has length > 0

    n_sorted_lists = [iter(l) for l in n_sorted_lists]
    cp = [next(i) for i in n_sorted_lists]

    merged = []

    while True:
        min_ele_idx, min_ele = get_min(cp)
        merged.append(min_ele)

        min_ele_list = n_sorted_lists[min_ele_idx]
        try:
            m = next(min_ele_list)
            cp[min_ele_idx] = m
        except StopIteration:
            n_sorted_lists.remove(min_ele_list)
            del cp[min_ele_idx]
            if len(cp) == 0:
                break
    return merged

def get_min(l):
    m_idx, m = -1, math.inf
    for i, v in enumerate(l):
        if v < m:
            m_idx = i
            m = v
        else:
            pass
    return m_idx, m

l = [7, 3, 8, 10, 11, 1, 6]
print(l)
s = merge_sort(l)
print(s)