mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-04-30 04:36:08 -04:00
organized
This commit is contained in:
parent
77731415d1
commit
5ed530430c
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -17,7 +18,6 @@ def binary_search(seq, key):
|
|||||||
hi = mid
|
hi = mid
|
||||||
else:
|
else:
|
||||||
lo = mid + 1
|
lo = mid + 1
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def binary_search_rec(seq, key, lo=0, hi=None):
|
def binary_search_rec(seq, key, lo=0, hi=None):
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
''' Searches an element in a matrix where in every row, the values are increasing from left to right, but the last number in a row is smaller than the first number in the next row.
|
''' Searches an element in a matrix where in every row, the values are increasing from left to right, but the last number in a row is smaller than the first number in the next row.
|
||||||
|
|
@ -1,25 +1,11 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
''' Given a sorted array that was rotated, find an item with binary search:
|
''' Given a sorted array that was rotated, find an item with binary search:
|
||||||
>>> l1 = [3, 4, 5, 6, 7, 1, 2]
|
|
||||||
>>> find_element_rot_array(l1, 7)
|
|
||||||
4
|
|
||||||
>>> find_element_rot_array(l1, 3)
|
|
||||||
0
|
|
||||||
>>> find_element_rot_array(l1, 4)
|
|
||||||
1
|
|
||||||
>>> find_element_rot_array(l1, 5)
|
|
||||||
2
|
|
||||||
>>> find_element_rot_array(l1, 6)
|
|
||||||
3
|
|
||||||
>>> find_element_rot_array(l1, 1)
|
|
||||||
5
|
|
||||||
>>> find_element_rot_array(l1, 2)
|
|
||||||
6
|
|
||||||
>>> find_element_rot_array(l1, 8)
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
def find_element_rot_array(seq, key, lo=0, hi=None):
|
def find_element_rot_array(seq, key, lo=0, hi=None):
|
||||||
@ -47,10 +33,12 @@ def find_element_rot_array(seq, key, lo=0, hi=None):
|
|||||||
return find_element_rot_array(seq, key, lo, mid)
|
return find_element_rot_array(seq, key, lo, mid)
|
||||||
|
|
||||||
|
|
||||||
|
def test_find_element_rot_array():
|
||||||
|
l1 = [3, 4, 5, 6, 7, 1, 2]
|
||||||
|
assert(find_element_rot_array(l1, 7) == 4 )
|
||||||
|
print("Tests passed!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import doctest
|
test_find_element_rot_array()
|
||||||
doctest.testmod()
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_max_unimodal_array(A):
|
def find_max_unimodal_array(A):
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
''' Given a sorted an array with empty strings, we use binary search to find some string (since
|
''' Given a sorted an array with empty strings, we use binary search to find some string (since
|
||||||
the list is sorted):
|
the list is sorted):
|
||||||
--> we deal with the empty strings with strip and then run to left and right, or move
|
--> we deal with the empty strings with strip and then run to left and right, or move
|
||||||
mid to the closed non-empty str (remember that the index must be conserved):
|
mid to the closed non-empty str (remember that the index must be conserved):
|
||||||
>>> l1 = ['acre', 'ball', '', 'coach', '', 'cut', '']
|
|
||||||
>>> find_str_array_with_empty_str(l1, l1[0])
|
|
||||||
0
|
|
||||||
>>> find_str_array_with_empty_str(l1, l1[1])
|
|
||||||
1
|
|
||||||
>>> find_str_array_with_empty_str(l1, l1[3])
|
|
||||||
3
|
|
||||||
>>> find_str_array_with_empty_str(l1, l1[5])
|
|
||||||
5
|
|
||||||
>>> find_str_array_with_empty_str(l1, 'bla')
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +38,12 @@ def find_str_array_with_empty_str(seq, s1):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
def test_find_str_array_with_empty_str():
|
||||||
import doctest
|
seq = ['acre', 'ball', '', 'coach', '', 'cut', '']
|
||||||
doctest.testmod()
|
key = seq[1]
|
||||||
|
assert(find_str_array_with_empty_str(seq, key) == 1)
|
||||||
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_find_str_array_with_empty_str()
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
def binary_serch_counting(lst1, k, lo=0, hi=None):
|
def binary_serch_counting(lst1, k, lo=0, hi=None):
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
''' using sets '''
|
''' using sets '''
|
||||||
|
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def ordered_sequential_search(seq, n):
|
def ordered_sequential_search(seq, n):
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sequential_search(seq, n):
|
def sequential_search(seq, n):
|
||||||
@ -29,4 +31,4 @@ if __name__ == '__main__':
|
|||||||
Case Best Case Worst Case Average Case
|
Case Best Case Worst Case Average Case
|
||||||
item is present 1 n n2
|
item is present 1 n n2
|
||||||
item is not present n n n
|
item is not present n n n
|
||||||
""""
|
"""
|
@ -1,112 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
''' A recursive and an iterative example of binary search in Python.
|
|
||||||
Remember: sequence must be sorted! You can return True/False or the index:
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6, 7]
|
|
||||||
>>> binary_search_rec(l1, 1)
|
|
||||||
0
|
|
||||||
>>> binary_search_rec(l1, 2)
|
|
||||||
1
|
|
||||||
>>> binary_search_rec(l1, 3)
|
|
||||||
2
|
|
||||||
>>> binary_search_rec(l1, 4)
|
|
||||||
3
|
|
||||||
>>> binary_search_rec(l1, 5)
|
|
||||||
4
|
|
||||||
>>> binary_search_rec(l1, 6)
|
|
||||||
5
|
|
||||||
>>> binary_search_rec(l1, 7)
|
|
||||||
6
|
|
||||||
>>> binary_search_rec(l1, 8)
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6]
|
|
||||||
>>> binary_search_rec(l1, 1)
|
|
||||||
0
|
|
||||||
>>> binary_search_rec(l1, 2)
|
|
||||||
1
|
|
||||||
>>> binary_search_rec(l1, 3)
|
|
||||||
2
|
|
||||||
>>> binary_search_rec(l1, 4)
|
|
||||||
3
|
|
||||||
>>> binary_search_rec(l1, 5)
|
|
||||||
4
|
|
||||||
>>> binary_search_rec(l1, 6)
|
|
||||||
5
|
|
||||||
>>> binary_search_rec(l1, 7)
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6, 7]
|
|
||||||
>>> binary_search_iter(l1, 1)
|
|
||||||
0
|
|
||||||
>>> binary_search_iter(l1, 2)
|
|
||||||
1
|
|
||||||
>>> binary_search_iter(l1, 3)
|
|
||||||
2
|
|
||||||
>>> binary_search_iter(l1, 4)
|
|
||||||
3
|
|
||||||
>>> binary_search_iter(l1, 5)
|
|
||||||
4
|
|
||||||
>>> binary_search_iter(l1, 6)
|
|
||||||
5
|
|
||||||
>>> binary_search_iter(l1, 7)
|
|
||||||
6
|
|
||||||
>>> binary_search_iter(l1, 8)
|
|
||||||
>>> l1 = [1, 2, 3, 4, 5, 6]
|
|
||||||
>>> binary_search_iter(l1, 1)
|
|
||||||
0
|
|
||||||
>>> binary_search_iter(l1, 2)
|
|
||||||
1
|
|
||||||
>>> binary_search_iter(l1, 3)
|
|
||||||
2
|
|
||||||
>>> binary_search_iter(l1, 4)
|
|
||||||
3
|
|
||||||
>>> binary_search_iter(l1, 5)
|
|
||||||
4
|
|
||||||
>>> binary_search_iter(l1, 6)
|
|
||||||
5
|
|
||||||
>>> binary_search_iter(l1, 7)
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
def binary_search_iter(seq, key):
|
|
||||||
hi, lo = len(seq), 0
|
|
||||||
while lo < hi: # here is <!
|
|
||||||
mid = (hi+lo)//2
|
|
||||||
if key == seq[mid]: return mid
|
|
||||||
elif key < seq[mid]: hi = mid
|
|
||||||
else: lo = mid + 1
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def bool_binary_search_iter(seq, key):
|
|
||||||
hi, lo = len(seq), 0
|
|
||||||
while lo < hi:
|
|
||||||
mid = (hi+lo)//2
|
|
||||||
if key == seq[mid]: return True
|
|
||||||
elif key < seq[mid]: hi = mid
|
|
||||||
else: lo = mid + 1
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def binary_search_rec(seq, key, lo=0, hi=None):
|
|
||||||
hi = hi or len(seq)
|
|
||||||
if hi <= lo: return None # base case: <= for odd and even numbers!
|
|
||||||
mid = (hi + lo) // 2
|
|
||||||
if key == seq[mid]: return mid
|
|
||||||
elif key < seq[mid] : return binary_search_rec(seq, key, lo, mid) # include until mid-1
|
|
||||||
else: return binary_search_rec(seq, key, mid+1, hi)
|
|
||||||
|
|
||||||
|
|
||||||
def bool_binary_search_rec(seq, key, lo=0, hi=None):
|
|
||||||
hi = hi or len(seq)
|
|
||||||
if hi <= lo: return False # base case: <= for odd and even numbers!
|
|
||||||
mid = (hi + lo) // 2
|
|
||||||
if key == seq[mid]: return True
|
|
||||||
elif key < seq[mid] : return bool_binary_search_rec(seq, key, lo, mid)
|
|
||||||
else: return bool_binary_search_rec(seq, key, mid+1, hi)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import doctest
|
|
||||||
doctest.testmod()
|
|
@ -1,16 +1,14 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
|
|
||||||
# Mari von Steinkirch @ 2013
|
__author__ = "Mari Wahl"
|
||||||
# mari.wahl9@gmail.com
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
# Bernardo Sulzbach (mafagafo) @ 2014
|
|
||||||
# 1449441@gmail.com
|
|
||||||
|
|
||||||
|
|
||||||
def bubble_sort(seq):
|
def bubble_sort(seq):
|
||||||
"""
|
"""
|
||||||
Implementation of bubble sort.
|
Implementation of bubble sort.
|
||||||
O(n²) and thus highly ineffective.
|
O(n2) and thus highly ineffective.
|
||||||
:param seq: the sequence to be sorted.
|
:param seq: the sequence to be sorted.
|
||||||
:return: the sorted sequence.
|
:return: the sorted sequence.
|
||||||
"""
|
"""
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
@ -54,6 +55,7 @@ def test_find_k_largest_seq_quickselect():
|
|||||||
seq = [3, 10, 4, 5, 1, 8, 9, 11, 5]
|
seq = [3, 10, 4, 5, 1, 8, 9, 11, 5]
|
||||||
k = 2
|
k = 2
|
||||||
assert(find_k_largest_seq_quickselect(seq,k) == [10, 11])
|
assert(find_k_largest_seq_quickselect(seq,k) == [10, 11])
|
||||||
|
print("Tests passed!")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
from do_benchmark import benchmark
|
|
||||||
|
|
||||||
@benchmark
|
|
||||||
def gnome_sort(seq):
|
def gnome_sort(seq):
|
||||||
''' sort a sequence using the gnome sort alg '''
|
''' sort a sequence using the gnome sort alg '''
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
class Heap(object):
|
class Heap(object):
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
85
src/searching_and_sorting/sorting/heap_sort.py
Normal file
85
src/searching_and_sorting/sorting/heap_sort.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
''' Heapsort using Pythons libraries'''
|
||||||
|
|
||||||
|
import heapq
|
||||||
|
|
||||||
|
def heap_sort1(seq):
|
||||||
|
''' heap sort with Python's heapq '''
|
||||||
|
h = []
|
||||||
|
for value in seq:
|
||||||
|
heapq.heappush(h, value)
|
||||||
|
return [heapq.heappop(h) for i in range(len(h))]
|
||||||
|
|
||||||
|
|
||||||
|
def test_heap_sort1():
|
||||||
|
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
|
assert(heap_sort1(seq) == sorted(seq))
|
||||||
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' Heapsort using my Heap class '''
|
||||||
|
|
||||||
|
from heap import Heap
|
||||||
|
|
||||||
|
def heap_sort2(seq):
|
||||||
|
heap = Heap(seq)
|
||||||
|
|
||||||
|
res = []
|
||||||
|
for i in range(len(seq)):
|
||||||
|
res.insert(0, heap.extract_max())
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def test_heap_sort2():
|
||||||
|
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
|
print heap_sort2(seq)
|
||||||
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
|
''' A third way of doing heap sort '''
|
||||||
|
|
||||||
|
def heap_sort3(seq):
|
||||||
|
for start in range((len(seq)-2)//2, -1, -1):
|
||||||
|
siftdown(seq, start, len(seq)-1)
|
||||||
|
for end in range(len(seq)-1, 0, -1):
|
||||||
|
seq[end], seq[0] = seq[0], seq[end]
|
||||||
|
siftdown(seq, 0, end - 1)
|
||||||
|
return seq
|
||||||
|
|
||||||
|
def siftdown(seq, start, end):
|
||||||
|
root = start
|
||||||
|
while True:
|
||||||
|
child = root * 2 + 1
|
||||||
|
if child > end: break
|
||||||
|
if child + 1 <= end and seq[child] < seq[child + 1]:
|
||||||
|
child += 1
|
||||||
|
if seq[root] < seq[child]:
|
||||||
|
seq[root], seq[child] = seq[child], seq[root]
|
||||||
|
root = child
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_heap_sort3():
|
||||||
|
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
|
assert(heap_sort3(seq) == sorted(seq))
|
||||||
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test_heap_sort1()
|
||||||
|
test_heap_sort2()
|
||||||
|
test_heap_sort3()
|
@ -1,23 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
import heapq
|
|
||||||
|
|
||||||
def heap_sort1(seq):
|
|
||||||
''' heap sort with Python's heapq '''
|
|
||||||
h = []
|
|
||||||
for value in seq:
|
|
||||||
heapq.heappush(h, value)
|
|
||||||
return [heapq.heappop(h) for i in range(len(h))]
|
|
||||||
|
|
||||||
|
|
||||||
def test_heap_sort1():
|
|
||||||
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
assert(heap_sort1(seq) == sorted(seq))
|
|
||||||
print('Tests passed!')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_heap_sort1()
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
from heap import Heap
|
|
||||||
|
|
||||||
def heap_sort2(seq):
|
|
||||||
heap = Heap(seq)
|
|
||||||
|
|
||||||
res = []
|
|
||||||
for i in range(len(seq)):
|
|
||||||
res.insert(0, heap.extract_max())
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
def test_heap_sort2():
|
|
||||||
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
assert(heap_sort2(seq) == sorted(seq))
|
|
||||||
print('Tests passed!')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_heap_sort2()
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
def heap_sort3(seq):
|
|
||||||
for start in range((len(seq)-2)//2, -1, -1):
|
|
||||||
siftdown(seq, start, len(seq)-1)
|
|
||||||
for end in range(len(seq)-1, 0, -1):
|
|
||||||
seq[end], seq[0] = seq[0], seq[end]
|
|
||||||
siftdown(seq, 0, end - 1)
|
|
||||||
return seq
|
|
||||||
|
|
||||||
def siftdown(seq, start, end):
|
|
||||||
root = start
|
|
||||||
while True:
|
|
||||||
child = root * 2 + 1
|
|
||||||
if child > end: break
|
|
||||||
if child + 1 <= end and seq[child] < seq[child + 1]:
|
|
||||||
child += 1
|
|
||||||
if seq[root] < seq[child]:
|
|
||||||
seq[root], seq[child] = seq[child], seq[root]
|
|
||||||
root = child
|
|
||||||
else:
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_heap_sort():
|
|
||||||
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
assert(heap_sort3(seq) == sorted(seq))
|
|
||||||
print('Tests passed!')
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test_heap_sort3()
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,23 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
''' Some examples of how to implement Merge Sort in Python
|
||||||
|
--> RUNTIME: WORST/BEST/AVERAGE Is O(nlogn)
|
||||||
|
--> space complexity is O(n) for arrays
|
||||||
|
--> not in place, good for large arrays
|
||||||
|
>>> seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
|
>>> merge_sort(seq) == sorted(seq)
|
||||||
|
True
|
||||||
|
>>> seq2 = [3, 3, 3, 3, 3, 3, 3, 3]
|
||||||
|
>>> merge_sort(seq2) == sorted(seq2)
|
||||||
|
True
|
||||||
|
>>> seq3 = []
|
||||||
|
>>> merge_sort(seq3) == sorted(seq3)
|
||||||
|
True
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
def merge_sort(seq):
|
def merge_sort(seq):
|
||||||
@ -22,12 +38,63 @@ def merge_sort(seq):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_merge_sort():
|
def test_merge_sort():
|
||||||
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
||||||
assert(merge_sort(seq) == sorted(seq))
|
assert(merge_sort(seq) == sorted(seq))
|
||||||
print('Tests passed!')
|
print('Tests passed!')
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
We could also divide this sort into two parts, separating
|
||||||
|
the merge part in another function
|
||||||
|
'''
|
||||||
|
|
||||||
|
def merge_sort_sep(seq):
|
||||||
|
if len(seq) < 2 : return seq # base case
|
||||||
|
mid = len(seq)//2
|
||||||
|
left, right = None, None # we could have declared the arrays here,
|
||||||
|
# but this would allocate unecessary extra space
|
||||||
|
if seq[:mid]: left = merge_sort(seq[:mid])
|
||||||
|
if seq[mid:]: right = merge_sort(seq[mid:]) # notice that mid is included!
|
||||||
|
|
||||||
|
return merge(left, right) # merge iteratively
|
||||||
|
|
||||||
|
def merge(left, right):
|
||||||
|
if not left or not right: return left or right # nothing to be merged
|
||||||
|
result = []
|
||||||
|
i, j = 0, 0
|
||||||
|
while i < len(left) and j < len(right):
|
||||||
|
if left[i] <= right[j]:
|
||||||
|
result.append(left[i])
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
result.append(right[j])
|
||||||
|
j += 1
|
||||||
|
if left[i:] : result.extend(left[i:]) # REMEMBER TO TO ENXTEND NOT APPEND
|
||||||
|
if right[j:] : result.extend(right[j:])
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
''' The two following merge functions are O(2n)=O(n) and O(n) respectively. They
|
||||||
|
illustrate many features in Python that '''
|
||||||
|
def merge_2n(left, right):
|
||||||
|
if not left or not right: return left or right # nothing to be merged
|
||||||
|
result = []
|
||||||
|
while left and right:
|
||||||
|
if left[-1] >= right[-1]:
|
||||||
|
result.append(left.pop())
|
||||||
|
else:
|
||||||
|
result.append(right.pop())
|
||||||
|
result.reverse()
|
||||||
|
return (left or right) + result
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
test_merge_sort()
|
test_merge_sort()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
''' --> In the case of two arrays: we can merge two arrays using the merge function from the merge sort
|
''' --> In the case of two arrays: we can merge two arrays using the merge function from the merge sort
|
||||||
--> we can do this for files too, merging each two
|
--> we can do this for files too, merging each two
|
@ -1,6 +1,27 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
|
''' Some examples of how to implement Quick Sort in Python
|
||||||
|
--> RUNTIME: BEST/AVERAGE Is O(nlogn), WORST is O(n2)
|
||||||
|
--> the first example is not in place, the second is in place
|
||||||
|
--> test with two element arrays, identical values
|
||||||
|
|
||||||
|
Quick sort in place:
|
||||||
|
1) select pivot as the index = 0
|
||||||
|
2) start pointer1 at index = 1 and pointer2 in the last element
|
||||||
|
3) while pointer1 < pointer2:
|
||||||
|
if value in pointer1 <= pivot
|
||||||
|
swap value in pointer1 with value in pointer2 and advanced pointer2
|
||||||
|
else
|
||||||
|
advance pointer1
|
||||||
|
4) now the array is like this:
|
||||||
|
[pivot, larger than pivot, smaller than pivot]
|
||||||
|
5) swap the pivot where pointer 1 stop
|
||||||
|
6) do recursively for [smaller] + [pivot] + [larger]
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -13,6 +34,19 @@ def quick_sort(seq):
|
|||||||
return left + [pivot] + right
|
return left + [pivot] + right
|
||||||
|
|
||||||
|
|
||||||
|
''' slightly different in the way we get the pivot'''
|
||||||
|
def quick_sort(seq):
|
||||||
|
if len(seq) < 2 : return seq
|
||||||
|
mid = len(seq)//2
|
||||||
|
pi = seq[mid]
|
||||||
|
seq = seq[:mid] + seq[mid+1:]
|
||||||
|
left = quick_sort([x for x in seq if x <= pi]) # REMEMBER TO INCLUDE X (OR IN RIGHT)
|
||||||
|
right = quick_sort([x for x in seq if x > pi])
|
||||||
|
return left + [pi] + right
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" we can also divide them into two functions """
|
""" we can also divide them into two functions """
|
||||||
def partition(seq):
|
def partition(seq):
|
||||||
pi,seq = seq[0],seq[1:]
|
pi,seq = seq[0],seq[1:]
|
||||||
@ -26,6 +60,23 @@ def quick_sort_divided(seq):
|
|||||||
return quick_sort_divided(lo) + [pi] + quick_sort_divided(hi)
|
return quick_sort_divided(lo) + [pi] + quick_sort_divided(hi)
|
||||||
|
|
||||||
|
|
||||||
|
''' quick_sort in place '''
|
||||||
|
def quick_sort_in(seq):
|
||||||
|
if len(seq) < 2 : return seq
|
||||||
|
if len(seq) == 2 and seq[0] > seq[1]:
|
||||||
|
seq[0], seq[1] = seq[1], seq[0] # problems when only 2 elements because of swap
|
||||||
|
pivot = seq[0] # start at the ends because we don't know how many elements
|
||||||
|
p1, p2 = 1, len(seq) -1 # set pointers at both ends
|
||||||
|
while p1 < p2: # must be < or out of range
|
||||||
|
if seq[p1] <= pivot: # must be <= because of pivot swap
|
||||||
|
seq[p1], seq[p2] = seq[p2], seq[p1]
|
||||||
|
p2 -= 1
|
||||||
|
else:
|
||||||
|
p1 += 1
|
||||||
|
seq[0], seq[p1] = seq[p1], pivot
|
||||||
|
return quick_sort_in(seq[p1+1:]) + [seq[p1]] + quick_sort_in(seq[:p1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_quick_sort():
|
def test_quick_sort():
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
|
|
||||||
def selection_sort(seq):
|
def selection_sort(seq):
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
__author__ = "Mari Wahl"
|
||||||
|
__email__ = "marina.w4hl@gmail.com"
|
||||||
|
|
||||||
''' A method to sort an array so that all the anagrams are together. Since we only
|
''' A method to sort an array so that all the anagrams are together. Since we only
|
||||||
want the anagrams to be grouped, we can use a dictionary for this task. This
|
want the anagrams to be grouped, we can use a dictionary for this task. This
|
@ -1,70 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
''' Some examples of how to implement Merge Sort in Python
|
|
||||||
--> RUNTIME: WORST/BEST/AVERAGE Is O(nlogn)
|
|
||||||
--> space complexity is O(n) for arrays
|
|
||||||
--> not in place, good for large arrays
|
|
||||||
>>> seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
>>> merge_sort(seq) == sorted(seq)
|
|
||||||
True
|
|
||||||
>>> seq2 = [3, 3, 3, 3, 3, 3, 3, 3]
|
|
||||||
>>> merge_sort(seq2) == sorted(seq2)
|
|
||||||
True
|
|
||||||
>>> seq3 = []
|
|
||||||
>>> merge_sort(seq3) == sorted(seq3)
|
|
||||||
True
|
|
||||||
'''
|
|
||||||
|
|
||||||
''' This is the main function that keep dividing the seq '''
|
|
||||||
def merge_sort(seq):
|
|
||||||
if len(seq) < 2 : return seq # base case
|
|
||||||
mid = len(seq)//2
|
|
||||||
left, right = None, None # we could have declared the arrays here,
|
|
||||||
# but this would allocate unecessary extra space
|
|
||||||
if seq[:mid]: left = merge_sort(seq[:mid])
|
|
||||||
if seq[mid:]: right = merge_sort(seq[mid:]) # notice that mid is included!
|
|
||||||
|
|
||||||
return merge(left, right) # merge iteratively
|
|
||||||
|
|
||||||
|
|
||||||
''' The two following merge functions are O(2n)=O(n) and O(n) respectively. They
|
|
||||||
illustrate many features in Python that '''
|
|
||||||
def merge_2n(left, right):
|
|
||||||
if not left or not right: return left or right # nothing to be merged
|
|
||||||
result = []
|
|
||||||
while left and right:
|
|
||||||
if left[-1] >= right[-1]:
|
|
||||||
result.append(left.pop())
|
|
||||||
else:
|
|
||||||
result.append(right.pop())
|
|
||||||
result.reverse()
|
|
||||||
return (left or right) + result
|
|
||||||
|
|
||||||
|
|
||||||
def merge(left, right):
|
|
||||||
if not left or not right: return left or right # nothing to be merged
|
|
||||||
result = []
|
|
||||||
i, j = 0, 0
|
|
||||||
while i < len(left) and j < len(right):
|
|
||||||
if left[i] <= right[j]:
|
|
||||||
result.append(left[i])
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
result.append(right[j])
|
|
||||||
j += 1
|
|
||||||
if left[i:] : result.extend(left[i:]) # REMEMBER TO TO ENXTEND NOT APPEND
|
|
||||||
if right[j:] : result.extend(right[j:])
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import doctest
|
|
||||||
doctest.testmod()
|
|
||||||
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# mari von steinkirch @2013
|
|
||||||
# steinkirch at gmail
|
|
||||||
|
|
||||||
|
|
||||||
''' Some examples of how to implement Quick Sort in Python
|
|
||||||
--> RUNTIME: BEST/AVERAGE Is O(nlogn), WORST is O(n2)
|
|
||||||
--> the first example is not in place, the second is in place
|
|
||||||
--> test with two element arrays, identical values
|
|
||||||
|
|
||||||
Quick sort in place:
|
|
||||||
1) select pivot as the index = 0
|
|
||||||
2) start pointer1 at index = 1 and pointer2 in the last element
|
|
||||||
3) while pointer1 < pointer2:
|
|
||||||
if value in pointer1 <= pivot
|
|
||||||
swap value in pointer1 with value in pointer2 and advanced pointer2
|
|
||||||
else
|
|
||||||
advance pointer1
|
|
||||||
4) now the array is like this:
|
|
||||||
[pivot, larger than pivot, smaller than pivot]
|
|
||||||
5) swap the pivot where pointer 1 stop
|
|
||||||
6) do recursively for [smaller] + [pivot] + [larger]
|
|
||||||
|
|
||||||
>>> seq = [3, 5, 2, 6, 8, 1, 0, 3, 5, 6, 2]
|
|
||||||
>>> quick_sort(seq) == sorted(seq)
|
|
||||||
True
|
|
||||||
>>> quick_sort([3, 3, 3, 3, 3, 3]) == [3, 3, 3, 3, 3, 3]
|
|
||||||
True
|
|
||||||
>>> quick_sort([]) == []
|
|
||||||
True
|
|
||||||
>>> quick_sort([2,1]) == [1, 2]
|
|
||||||
True
|
|
||||||
>>> quick_sort_in(seq) == sorted(seq)
|
|
||||||
True
|
|
||||||
>>> quick_sort_in([3, 3, 3, 3, 3, 3]) == [3, 3, 3, 3, 3, 3]
|
|
||||||
True
|
|
||||||
>>> quick_sort_in([]) == []
|
|
||||||
True
|
|
||||||
>>> quick_sort_in([2,1]) == [1, 2]
|
|
||||||
True
|
|
||||||
'''
|
|
||||||
|
|
||||||
def quick_sort(seq):
|
|
||||||
if len(seq) < 2 : return seq
|
|
||||||
mid = len(seq)//2
|
|
||||||
pi = seq[mid]
|
|
||||||
seq = seq[:mid] + seq[mid+1:]
|
|
||||||
left = quick_sort([x for x in seq if x <= pi]) # REMEMBER TO INCLUDE X (OR IN RIGHT)
|
|
||||||
right = quick_sort([x for x in seq if x > pi])
|
|
||||||
return left + [pi] + right
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def quick_sort_in(seq):
|
|
||||||
if len(seq) < 2 : return seq
|
|
||||||
if len(seq) == 2 and seq[0] > seq[1]:
|
|
||||||
seq[0], seq[1] = seq[1], seq[0] # problems when only 2 elements because of swap
|
|
||||||
pivot = seq[0] # start at the ends because we don't know how many elements
|
|
||||||
p1, p2 = 1, len(seq) -1 # set pointers at both ends
|
|
||||||
while p1 < p2: # must be < or out of range
|
|
||||||
if seq[p1] <= pivot: # must be <= because of pivot swap
|
|
||||||
seq[p1], seq[p2] = seq[p2], seq[p1]
|
|
||||||
p2 -= 1
|
|
||||||
else:
|
|
||||||
p1 += 1
|
|
||||||
seq[0], seq[p1] = seq[p1], pivot
|
|
||||||
return quick_sort_in(seq[p1+1:]) + [seq[p1]] + quick_sort_in(seq[:p1])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
import doctest
|
|
||||||
doctest.testmod()
|
|
Loading…
x
Reference in New Issue
Block a user