A fast set: sorted array:
class Sorted_Array_Set:
def __init__(self):
self.A = Array_Seq()
def __len__(self):
return len(self.A)
def __iter__(self):
yield from self.A
def iter_order(self):
yield from self
def build(self, X):
self.build()
self.sort()
# def sort(self):
def _binary_sort(self, k, i, j):
if i >= j: return i
m = (i + j) // 2
x = self.A.get_at(m)
if x.key > k: self._binary_sort(k, i, m - 1)
if x.key < k: self._binary_sort(k, m + 1, j)
return m
def find_min(self):
if len(self.A) > 0: return self.A.get_at(0)
def find_max(self):
if len(self.A) > 0: return self.A.get_at(len(self) - 1)
def find(self, k):
if len(A) == 0: return None
i = self._binary_sort(k, 0, len(self) - 1)
x = self.A.get_at(i)
if x.key == k:
return x
else:
return None
def find_next(self, k):
if len(self) == 0: return None
i = self._binary_sort(A, 0, len(self) - 1)
x = self.A.get_at(i)
if x.key > k: return x
if i + 1 < len:
return self.A.get_at(i + 1)
else:
return None
def find_pref(self, k):
if len(self) == 0: return None
i = self._binary_sort(A, 0, len(A) - 1)
x = self.A.get_at(i)
if x.key < k: return x
if i > 0:
return self.A.get_at(i - 1)
else:
return None
def delete(self, k):
i = self._binary_sort(l, 0, len(self.A) - 1)
assert self.get_at(i).key == k
return self.delete_at(i)
In this data structure, we can find the item easility by the binary research for time.
Selection Sort:
pattern 1
def selection_sort(A):
for i in range(len(A) - 1, 0, -1):
max = i
for j in range(i):
max = A[j]
A[max], A[i] = A[i], A[max]
pattern 2:
def selection_sort(A, i=None):
if i is None:
i = len(A) - 1
if i > 0:
j = prefix_max(A, i)
A[i], A[j] = A[j], A[i]
selection_sort(A, i - 1)
def prefix_max(A, i):
if i > 0:
j = prefix_max(A, i - 1)
if A[j] > A[i]:
return j
return i
Insertion_sort
def insertion_sort(A):
for i in range(1, len(A)):
j = i
while j > 0 and A[j] < A[j - 1]:
A[j], A[j - 1] = A[j - 1], A[j]
j = j - 1
Selection and Insertion Sort:
the same:
- Both are incremental in that they maintain, and grow a sorted subset until all the items are sorted.
- Both are in-place algorithms,using a constant space , don't need a more space
Differences:
- Selection sort:
- maintain the largest items
- Insertion sort:
- maintain the first i input
Insertion Sort is more stable,the output will be the same from the same input.
Merge_sort
def merge_sort(A, a=0, b=None):
if b == None: b = len(A)
if b - a > 1:
c = (a + b + 1) // 2
merge_sort(A, a, c)
merge_sort(A, c, b)
L, R = A[a:c], A[c:b]
i, j = 0, 0
while a < b:
if (j >= len(R)) or (i < len(L) and L[i] < R[j]):
A[a] = L[i]
i = i + 1
else:
A[a] = R[j]
j = j + 1
a = a + 1
We need a temporary space to combine the two halves.It's not in-space algorithm.
Build a sorted array:
sacrifice some time in building the data structure to speed up our order queries,which is called preprocessing.