# 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")