- Бавни алгоритми за сортиране
- Бързи алгоритми за сортиране
- Сортиране с броене
- Кой сортиращ алгоритъм използва методът sort() в Python?
Решения от контролно 1 - тук.
- хибриден алгоритъм - комбинира Merge sort и Insertion sort
- O(NlogN) сложност по време
- О(N) сложност по време в най-добрия случай
- О(N) сложност по памет
- стабилен сортиращ алгоритъм
Масивът се разделя на парчета. Всяко парче се сортира с Insertion sort. След това парчетата се съединяват чрез Merge операцията от Merge sort.
Примерна имплементация:
def timsort(arr):
return sorted(arr)Реалната имплементация използва по-сложни техники.
- Linear search
- Binary search
- Ternary search
- Jump search
- Exponential search
- работи за сортирани и несортирани данни
- O(N) сложност по време
- подходящ за малък брой заявки при несортирани данни
Всеки елемент от масива се сравнява последователно с търсения.
def linear_search(arr, X):
for i in range(len(arr)):
if arr[i] == X:
return i
return -1
arr = [9, 4, 3, 2, 6, 7, 1, 8, 5]
X = 6
print(linear_search(arr, X)) # 4- работи само за сортирани данни
- O(logN) сложност по време
- подходящ за много наброй заявки
Сравнява се средния елемент с търсения. Ако търсеният елемент е по-малък, разглежда се масива отляво на средния елемент. Ако търсеният е по-голям, разглежда се масива отдясно на средния. Стъпките се повтарят до намиране на елемента.
def binary_search(arr, X):
left = 0
right = len(arr) - 1
Xi = 0
while left <= right:
mid = left + (right - left) // 2
if X <= arr[mid]:
right = mid - 1
Xi = mid
else:
left = mid + 1
return Xi
arr = [10, 20, 30, 40, 50, 60, 70, 80, 90]
X = 60
Xi = binary_search(arr, X)
print(Xi) # 5- работи за сортирани и параболични данни
- O(log3N) сложност по време
- подходящ за намиране на единствен максимум/ минимум на функция
Сравняват се двата средни елементи с търсения. Ако търсеният елемент е по-малък от първия среден, разглежда се масива отляво на първия среден елемент. Ако търсеният е между двата средни, разглежда се втората третина от масива. Ако търсеният е по-голям от втория среден елемент - разглежда се масива отдясно на втория среден елемент. Отново стъпките се повтарят до намиране на елемента.
def ternarySearch(arr, key, l, r):
if r >= l:
mid1 = l + (r - l) //3
mid2 = r - (r - l) //3
if arr[mid1] == key:
return mid1
if arr[mid2] == key:
return mid2
if key < arr[mid1]:
return ternarySearch(arr, key, l, mid1 - 1)
elif key > arr[mid2]:
return ternarySearch(arr, key, mid2 + 1, r)
else:
return ternarySearch(arr, key, mid1 + 1, mid2 - 1)
return -1
arr = [10, 20, 30, 40, 50, 60, 70, 80, 90]
X = 60
Xi = ternarySearch(arr, X, 0, len(arr) - 1)
print(Xi) # 5- работи само за сортирани данни
- оптималният скок е sqrt(N) (за минимален общ брой сравнения)
- O(sqrt(N)) сложност по време
- по-бавен от Binary search (O(log(N)) < O(sqrt(N)) < O(N))
Търсеният елемент се сравнява последователно с елементи на позиции, кратни на стъпката (корен от N). Когато търсеният елемент стане по-малък от елемента на K-та стъпка, се извършва линейно търсене в интервала (K-1)-ва стъпка до K-та стъпка.
Jump search прави 1 връщане назад в масива, докато при Binary search има най-много logN връщания. При нужда от ограничаване на връщанията Jump search е предпочитан пред Binary search въпреки по-голямата сложност по време. Точно поради тази причина не се извършва двоично търсене в намерения интервал.
import math
def jumpSearch(arr, X):
N = len(arr)
block_size = int(math.sqrt(N))
step = block_size
prev = 0
while arr[min(step, N) - 1] < X:
prev = step
step += block_size
if prev >= N:
return -1
while arr[prev] < X:
prev += 1
if prev == min(step, N):
return -1
if arr[prev] == X:
return prev
return -1
arr = [10, 20, 30, 40, 50, 60, 70, 80, 90]
X = 50
Xi = jumpSearch(arr, X)
print(Xi) # 4- работи само за сортирани данни
- O(logi) сложност по време, където i е позицията на числото
- подходящ при търсене на елементи, намиращи се в началото на масива (i < N)
Търсеният елемент се сравнява последователно с елементи на позиции, степени на двойката (2K). Когато търсеният елемент стане по-малък от елемента на К-та степен, се извършва двоично търсене в интервала 2K-1-ва позиция до 2K-та позиция.
def exponential_search(arr, X):
N = len(arr)
i = 1
while i < N and arr[i] <= X:
i = i * 2
left = i // 2
right = min(i, N-1)
return binary_search(arr, X, left, right)
arr = [10, 20, 30, 40, 50, 60, 70, 80, 90]
X = 60
Xi = exponential_search(arr, X)
print(Xi) # 5Решения на задачите: тук