算法导论 python代码 第九章

# author Ttssxuan
# chapter 9.1

# the algorithm for finding the minimum in an array
def minimum(arr):
    '''
    find the minimum in an array

    Parameters:
        arr - the array need to find the ninimum
    Returns:
        the index of the minimum
    '''
    min = 0
    for i in range(1, len(arr)):
        if arr[min] > arr[i]:
            min = i
    return min

# test
arr = [5, 1, 0, 7, 1, 3, 8]
print("the minimum: ", arr[minimum(arr)])


from math import ceil

# the algorithm for finding the minimum and the maximum in an array
def minimum_maximum(arr):
    '''
    find the maximum and the minimum

    Parameters:
        arr - the array need to find the maximum and the minimum
    Returns:
        the index of the maximum and the minimum
    '''
    # init the min and the max 
    if len(arr) % 2 == 0:
        max = 1
        min = 0
    else:
        max = min = 0

    i = max + 1
    # compare the pair and use the smaller compares to the min, use the larger
    # compares to the max
    while i + 1 <= len(arr) - 1:
        if arr[i] < arr[i + 1]:
            a = i
            b = i + 1
        else:
            a = i + 1
            b = i
        if arr[a] < arr[min]:
            min = a
        if arr[b] > arr[max]:
            max = b
        i = i + 2

    return max, min

# test
arr = [2, 0, 1, 3, 9, 10, 11]
max, min = minimum_maximum(arr)
print("the minimum: ", arr[min], " the maximum: ", arr[max])



# author Ttssxuan
# chapter 9.2
# the randomized select

import random

def randomized_select(arr, p, r, i):
    '''
    find the ith element in the arr[p..r]

    Parameters:
        arr - the elements set
        p - the beginning of the array
        r - the ending of the array
        i - the element order
    Returns:
        the ith element
    '''
    if p == r:
        return arr[p]
    # get the partition point
    q = random_partition(arr, p, r)
    k = q - p + 1
    # get the new range of the ith element
    if i == k:
        return arr[q]
    elif i < k:
        return randomized_select(arr, p, q - 1, i)
    else:
        return randomized_select(arr, q + 1, r, i - k)

def random_partition(arr, p, r):
    '''
    get a partition of the arr

    Parameters:
        arr - the array need to be divided
        p - the begining of the array
        r - the ending of the array
    Returns:
        the partition point
    '''
    # random choose an element as a partition
    temp = random.randint(p, r)
    arr[r], arr[temp] = arr[temp], arr[r]
    # divide the array
    i = p - 1
    for j in range(p, r):
        if arr[j] <= arr[r]:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
    arr[r], arr[i + 1] = arr[i + 1], arr[r]
    return i + 1

# test
print("test randomized select")
arr = [1, 2, 4, 8, 9, 10, 2, 5, 3]
print("4th: ", randomized_select(arr, 0, len(arr) - 1, 4))
print("5th: ", randomized_select(arr, 0, len(arr) - 1, 5))
print("7th: ", randomized_select(arr, 0, len(arr) - 1, 7))


def randomized_select_iterative(arr, p, r, i):
    '''
    find the ith element in arr, using the iterative

    Parameters:
        arr - the element set
        p - the beginning of the arr
        r - the ending of the arr
        i - the ith element
    Returns:
        the ith element
    '''
    if p == r:
        return arr[p]
    while True:
        if p == r:
            return arr[p]
        q = random_partition(arr, p, r)
        k = q - p + 1
        if i == k:
            return arr[q]
        elif i < k:
            r = q - 1
        else:
            p = q + 1
            i = i - k

# test
print("randomized select iterative")
arr = [1, 2, 4, 8, 9, 10, 2, 5, 3]
print("4th: ", randomized_select_iterative(arr, 0, len(arr) - 1, 4))
print("5th: ", randomized_select_iterative(arr, 0, len(arr) - 1, 5))
print("7th: ", randomized_select_iterative(arr, 0, len(arr) - 1, 7))


# author Ttssxuan
# 9.3-8
# find the median of the two array

from math import floor

def two_array_median(arrX, arrY):
    '''
    find the median of the two sorted arrX and arrY

    Parameters:
        arrX - the first array
        arrY - the second array
    Returns:
        the index of the median, and the flag of the array
    '''
    n = len(arrX) - 1
    median = find_median(arrX, arrY, n, 0, n)
    arr_num = 0
    if median == -1:
        median = find_median(arrY, arrX, n, 0, n)
        arr_num = 1
    return median, arr_num

def find_median(arrA, arrB, n, low, high):
    '''
    find the median of the two array with the given bound

    Parameters:
        arrA - the first array
        arrB - the second array
        n - the length of the array
        low - the lower bound of the array
        high - the higher bound of the array
    Returns:
        the index of the median
    '''
    if low > high:
        return -1
    else:
        k = int(floor((low + high) / 2))
        if k == n and arrA[n] <= arrB[0]:
            return n
        elif k < n and arrB[n - k - 1] <= arrA[k] <= arrB[n - k]:
            return k
        elif arrA[k] > arrB[n - k]:
            return find_median(arrA, arrB, n, low, k - 1)
        else:
            return find_median(arrA, arrB, n, k + 1, high)


# test
arrX = [1, 2, 4, 5, 6, 8]
arrY = [0, 1, 3, 4, 7, 8]
median, arr_num = two_array_median(arrX, arrY)
if arr_num == 0:
    print("arrX:", arrX[median], median)
else:
    print("arrY:", arrY[median], median)


# author Ttssxuan
# chapter 9-2
# the find median with 0(nlgn)

import random

# the element define
class element:
    def __init__(self, value, weight):
        self.value = value
        self.weight = weight

def find_median(arr, p, r, weight):
    '''
    find the median as the problem claim

    Parameters:
        arr - the array needs to find the median
        p - the beginning of the array
        r - the ending of the array
        weight - the total weight of arr[0..p]
    Returns:
        the median index of the array
    '''
    if p == r:
        return p
    # get the partion and the conrespond weight
    q, left_weight = partition(arr, p, r)
    # verify the condition whether fulfill and do the conrespond action
    total = weight + left_weight
    if 1 - total - arr[q].weight <= 0.5 and total < 0.5:
        return q
    elif total >= 0.5:
        return find_median(arr, p, q - 1, weight)
    else:
        return find_median(arr, q + 1, r, total + arr[q].weight)

def partition(arr, p, r):
    '''
    get a partition of the arr[p..r]

    Parameters:
        arr - the array need to divide
        p - the beginning of the array
        r - the ending of the array
    Returns:
        the partition index and the sum of the weight arr[p..index]
    '''
    # get a random starting
    temp = random.randint(p, r)
    arr[temp], arr[r] = arr[r], arr[temp]
    i =  p - 1
    weight = 0
    for j in range(p, r):
        if arr[j].value < arr[r].value:
            i += 1
            arr[i], arr[j] = arr[j], arr[i]
            # get the sum of the wieght of the element less than arr[j].value
            weight += arr[i].weight
    arr[i + 1], arr[r] = arr[r], arr[i + 1]
    return i + 1, weight

# test
print("test 1")
arr = [element(2, 0.1), element(1, 0.2), element(5, 0.4), element(3, 0.1), element(10, 0.2)]
pos = find_median(arr, 0, len(arr) - 1, 0)
if pos != -1:
    print(arr[pos].value)
else:
    print("no such element")

print("test 2")
arr = [element(10, 1)]
pos = find_median(arr, 0, len(arr) - 1, 0)
if pos != -1:
    print(arr[pos].value)
else:
    print("no such element")

print("test 3")
arr = [element(2, 0.1), element(1, 0.9)]
pos = find_median(arr, 0, len(arr) - 1, 0)
if pos != -1:
    print(arr[pos].value)
else:
    print("no such element")


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值