算法学习(二)对数器(python实现)、递归行为时间复杂度估算、归并排序时间复杂度

一、对数器

1、用途:验证算法是否正确的一种方式。

2、使用:

(1)有一个想测的方法func

(2)实现一个绝对正确但是复杂度不好的方法RightMathod

(3)实现一个随机样本产生器

(4)实现比对的方法

(5)把方法a和方法b比对很多次来验证方法a是否正确

(6)如果有一个样本使得比对出错,打印样本分析是哪个方法出错

(7)当样本数量很多时比对测试依然正确,可以确定方法func已经正确

3、实现:

(1)随机数组生成器:长度和数字都是随机的:GenerateRandomArray(size, value)

(2)一个绝对正确的方法:RightMathod(array)

(3)IsRight(times, size, value, func)

import random, operator


def GenerateRandomArray(size, value): # 产生一个随机数列长度为size,数字范围为-value~value
    array =[]
    for i in range(size):
        array.append(int((value + 1) * random.random()) - int(value * random.random()))
    return array


def RightMathod(array): # 一定正确的方法:自带排序方法
    array.sort()
    return array


def IsRight(times, size, value, func): # 次数、长度、数字范围、测试方法
    succeed = True
    for i in range(times):
        arr1 = GenerateRandomArray(size, value)
        arr2 = arr1.copy()
        arr3 = arr1.copy()
        func(arr1)
        RightMathod(arr2)
        if not operator.eq(arr1, arr2):
            succeed = False
            print(arr3)
            break
    print("NICE" if succeed == True else "WRONG")


IsRight(500000, 10, 100, selectionSort)

二、递归行为和递归行为时间复杂度的估算

def getMax(array, L, R):
    if L == R:
        return array[L]
    mid = int((L + R) / 2)
    maxLeft = getMax(array, L, mid)
    maxRight = getMax(array, mid + 1, R)
    return max(maxLeft, maxRight)

l = [4,3,2,1]
print(getMax(l, 0, len(l) - 1))

递归(划分的子过程规模相同):     

(1)log(b,a) > d -> 复杂度为O(N^log(b,a))

(2)log(b,a) = d -> 复杂度为O(N^d * logN)

(3)log(b,a) < d -> 复杂度为O(N^d)

三、归并排序时间复杂度估算

          T(N)=2T(\frac{N}{2})+o(N)

def Merge(array, L, mid, R):
    help = []
    i = 0
    p1 = L
    p2 = mid + 1
    while p1 <= mid and p2 <=R:
        if array[p1] < array[p2]:
            help[i] = array[p1]
            p1 += 1
        else:
            help[i] = array[p2]
            p2 += 1
        i += 1
    while p1 <= mid:
        help[i] = array[p1]
        i += 1
        p1 +=1
    while p2 <= R:
        help[i] = array[p2]
        i += 1
        p2 +=1
    for k in range(0, len(help)):
        array[L + k] = help[k]
    return array

def SortProcess(array, L, R):
    if L == R:
        return array[L]
    mid = int((L + R) / 2)
    SortProcess(array, mid + 1, R)
    SortProcess(array, L, mid)
    Merge(array, L, mid, R)

四、小和问题和逆序对问题

1、小和问题:在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组
的小和。
   例子:
                [1,3,4,2,5]
                1左边比1小的数,没有;
                3左边比3小的数,1;
                4左边比4小的数,1、3;
                2左边比2小的数,1;
                5左边比5小的数,1、3、4、2;
                所以小和为1+1+3+1+1+3+4+2=16

def SmallSum(array):
    if array == None or len(array) < 2:
        return 0
    return MergeSort(array, 0, len(array) - 1)

def MergeSort(array, L, R):
    if L == R :
        return 0
    mid = int(L + ((R - L) >> 1))
    return MergeSort(array, L, mid) +\
           MergeSort(array, mid + 1, R) + \
           Merge(array, L, mid, R)

def Merge(array, L, mid, R):
    help = []
    i = 0
    p1 = L
    p2 = mid + 1
    res = 0
    while p1 <= mid and p2 <=R:
        res += (R - p2 + 1) * array[p1] if array[p1] < array[p2] else 0
        if array[p1] < array[p2]:
            help[i] = array[p1]
            p1 += 1
        else:
            help[i] = array[p2]
            p2 += 1
        i += 1
    while p1 <= mid:
        help[i] = array[p1]
        i += 1
        p1 +=1
    while p2 <= R:
        help[i] = array[p2]
        i += 1
        p2 +=1
    for k in range(0, len(help)):
        array[L + k] = help[k]
    return res

l = [1,3,4,2,5]
print(MergeSort(l,0,len(l)))


 

猜你喜欢

转载自blog.csdn.net/qq_28334183/article/details/82798279