在python中合并排序而不使用递归进行切片

时间:2017-02-24 00:21:52

标签: python algorithm recursion

这是我在python中进行合并排序的解决方案。

我的笔记:

  1. 由于递归中的堆栈,时间是2n(log(n))而不是n(log(n))。我无法找到解决此问题的方法。
  2. 自下而上的递归方法实际上更容易,并且是n(log(n))
  3. 我见过使用切片的解决方案。例如:

    lefthalf = alist [:mid] righthalf = alist [mid:] 归并排序(lefthalf) 归并排序(righthalf)

  4. 然而,这些解决方案忽略切片花费k时间,因为切片需要k次。所以上面的代码实际上是:

    lefthalf = []
    
    for i in range(mid): #k times
        lefhalf.append(alist[i])
    for i in range(mid, len(alist): #k times
        righthalf.append(alist[i])
    

    我的解决方案:

    import random
    def _merge_sort(indices, the_list):
        start = indices[0]
        end = indices[1]
        half_way = (end - start)//2 + start
        if start < half_way:
            _merge_sort((start, half_way), the_list)
        if half_way + 1 <= end and end - start != 1:
           _merge_sort((half_way + 1, end), the_list)
        #a stack is created using log(n) number of recursions
        sort_sub_list(the_list, indices[0], indices[1])
    
    
    def sort_sub_list(the_list, start, end):
        orig_start = start
        initial_start_second_list = (end - start)//2 + start + 1
        list2_first_index = initial_start_second_list
        new_list = []
        while start < initial_start_second_list and list2_first_index <= end:
            first1 = the_list[start]
            first2 = the_list[list2_first_index]
            if first1 > first2:
                new_list.append(first2)
                list2_first_index += 1
            else:
                new_list.append(first1)
                start += 1
        while start < initial_start_second_list:
            new_list.append(the_list[start])
            start += 1
    
        while list2_first_index <= end:
            new_list.append(the_list[list2_first_index])
            list2_first_index += 1
        # at this point, the total number each while statement ran is  n
        # now we have to do n again!
        for i in new_list:
            the_list[orig_start] = i
            orig_start += 1
    
    
    def merge_sort(the_list):
        return _merge_sort((0, len(the_list) - 1), the_list)
    
    if __name__ == '__main__':
        for i in range(100):
            n = 100
            l = range(n)
            random.shuffle(l)
            merge_sort(l)
            assert l == range(n)
    

0 个答案:

没有答案