Sortings and searching algorithms refactoring

This commit is contained in:
Sergey Tsaplin 2016-07-30 01:06:49 +05:00
parent f875a1ba5b
commit 1459957c06
13 changed files with 441 additions and 251 deletions

90
.gitignore vendored Normal file
View File

@ -0,0 +1,90 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# IPython Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# dotenv
.env
# virtualenv
venv/
ENV/
# Spyder project settings
.spyderproject
# Rope project settings
.ropeproject
.idea

View File

@ -1,39 +0,0 @@
import sys
def simple_bubble_sort(int_list):
count = len(int_list)
swapped = True
while (swapped):
swapped = False
for j in range(count - 1):
if (int_list[j] > int_list[j + 1]):
int_list[j], int_list[j + 1] = int_list[j + 1], int_list[j]
swapped = True
return int_list
def main():
# Python 2's `raw_input` has been renamed to `input` in Python 3
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
try:
print("Enter numbers separated by spaces:")
s = input_function()
inputs = list(map(int, s.split(' ')))
if len(inputs) < 2:
print('No Enough values to sort!')
raise Exception
except Exception as e:
print(e)
else:
sorted_input = simple_bubble_sort(inputs)
print('\nSorted list (min to max): {}'.format(sorted_input))
if __name__ == '__main__':
print('==== Bubble Sort ====\n')
main()

View File

@ -1,40 +0,0 @@
import sys
def simple_insertion_sort(int_list):
count = len(int_list)
for i in range(1, count):
temp = int_list[i]
j = i - 1
while(j >= 0 and temp < int_list[j]):
int_list[j + 1] = int_list[j]
j -= 1
int_list[j + 1] = temp
return int_list
def main():
# Python 2's `raw_input` has been renamed to `input` in Python 3
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
try:
print("Enter numbers separated by spaces:")
s = input_function()
inputs = list(map(int, s.split(' ')))
if len(inputs) < 2:
print('No Enough values to sort!')
raise Exception
except Exception as e:
print(e)
else:
sorted_input = simple_insertion_sort(inputs)
print('\nSorted list (min to max): {}'.format(sorted_input))
if __name__ == '__main__':
print('==== Insertion Sort ====\n')
main()

View File

@ -1,32 +0,0 @@
import sys
def sequential_search(alist, target):
for index, item in enumerate(alist):
if item == target:
print("Found target {} at index {}".format(target, index))
break
else:
print("Not found")
def main():
# Python 2's `raw_input` has been renamed to `input` in Python 3
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
try:
print("Enter numbers separated by spaces")
s = input_function()
inputs = list(map(int, s.split(' ')))
target = int(input_function('\nEnter a number to be found in list: '))
except Exception as e:
print(e)
else:
sequential_search(inputs, target)
if __name__ == '__main__':
print('==== Linear Search ====\n')
main()

View File

@ -1,59 +0,0 @@
import sys
def merge_sort(alist):
print("Splitting ", alist)
if len(alist) > 1:
mid = len(alist) // 2
left_half = alist[:mid]
right_half = alist[mid:]
merge_sort(left_half)
merge_sort(right_half)
i = j = k = 0
while i < len(left_half) and j < len(right_half):
if left_half[i] < right_half[j]:
alist[k] = left_half[i]
i += 1
else:
alist[k] = right_half[j]
j += 1
k += 1
while i < len(left_half):
alist[k] = left_half[i]
i += 1
k += 1
while j < len(right_half):
alist[k] = right_half[j]
j += 1
k += 1
print("Merging ", alist)
return alist
def main():
# Python 2's `raw_input` has been renamed to `input` in Python 3
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
try:
print("Enter numbers separated by spaces:")
s = input_function()
inputs = list(map(int, s.split(' ')))
if len(inputs) < 2:
print('No Enough values to sort!')
raise Exception
except Exception as e:
print(e)
else:
sorted_input = merge_sort(inputs)
print('\nSorted list (min to max): {}'.format(sorted_input))
if __name__ == '__main__':
print('==== Merge Sort ====\n')
main()

View File

@ -1,41 +0,0 @@
import sys
def quick_sort(A, p, r):
if p < r:
q = partition(A, p, r)
quick_sort(A, p, q - 1)
quick_sort(A, q + 1, r)
return A
def partition(A, p, r):
i = p - 1
for j in range(p, r):
if A[j] <= A[r]:
i += 1
A[i], A[j] = A[j], A[i]
A[i + 1], A[r] = A[r], A[i + 1]
return i + 1
def main():
# Python 2's `raw_input` has been renamed to `input` in Python 3
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
try:
print("Enter numbers separated by spaces")
s = input_function()
inputs = list(map(int, s.split(' ')))
except Exception as e:
print(e)
else:
sorted_input = quick_sort(inputs, 0, len(inputs) - 1)
print('\nSorted list (min to max): {}'.format(sorted_input))
if __name__ == '__main__':
print('==== Quick Sort ====\n')
main()

View File

@ -2,9 +2,9 @@
This is pure python implementation of binary search algorithm
For doctests run following command:
python -m doctest -v selection_sort.py
python -m doctest -v binary_search.py
or
python3 -m doctest -v selection_sort.py
python3 -m doctest -v binary_search.py
For manual testing run:
python binary_search.py
@ -13,30 +13,12 @@ from __future__ import print_function
import bisect
def assert_sorted(collection):
"""Check if collection is sorted. If not raises :py:class:`ValueError`
:param collection: collection
:return: True if collection is sorted
:raise: :py:class:`ValueError` if collection is not sorted
Examples:
>>> assert_sorted([0, 1, 2, 4])
True
>>> assert_sorted([10, -1, 5])
Traceback (most recent call last):
...
ValueError: Collection must be sorted
"""
if collection != sorted(collection):
raise ValueError('Collection must be sorted')
return True
def binary_search(sorted_collection, item):
"""Pure implementation of binary search algorithm in Python
Be careful collection must be sorted, otherwise result will be
unpredictable
:param sorted_collection: some sorted collection with comparable items
:param item: item value to search
:return: index of found item or None if item is not found
@ -53,12 +35,7 @@ def binary_search(sorted_collection, item):
>>> binary_search([0, 5, 7, 10, 15], 6)
>>> binary_search([5, 2, 1, 5], 2)
Traceback (most recent call last):
...
ValueError: Collection must be sorted
"""
assert_sorted(sorted_collection)
left = 0
right = len(sorted_collection) - 1
@ -78,6 +55,9 @@ def binary_search(sorted_collection, item):
def binary_search_std_lib(sorted_collection, item):
"""Pure implementation of binary search algorithm in Python using stdlib
Be careful collection must be sorted, otherwise result will be
unpredictable
:param sorted_collection: some sorted collection with comparable items
:param item: item value to search
:return: index of found item or None if item is not found
@ -94,18 +74,34 @@ def binary_search_std_lib(sorted_collection, item):
>>> binary_search_std_lib([0, 5, 7, 10, 15], 6)
>>> binary_search_std_lib([5, 2, 1, 5], 2)
Traceback (most recent call last):
...
ValueError: Collection must be sorted
"""
assert_sorted(sorted_collection)
index = bisect.bisect_left(sorted_collection, item)
if index != len(sorted_collection) and sorted_collection[index] == item:
return index
return None
def __assert_sorted(collection):
"""Check if collection is sorted, if not - raises :py:class:`ValueError`
:param collection: collection
:return: True if collection is sorted
:raise: :py:class:`ValueError` if collection is not sorted
Examples:
>>> __assert_sorted([0, 1, 2, 4])
True
>>> __assert_sorted([10, -1, 5])
Traceback (most recent call last):
...
ValueError: Collection must be sorted
"""
if collection != sorted(collection):
raise ValueError('Collection must be sorted')
return True
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
@ -117,6 +113,10 @@ if __name__ == '__main__':
user_input = input_function('Enter numbers separated by coma:\n')
collection = [int(item) for item in user_input.split(',')]
try:
__assert_sorted(collection)
except ValueError:
sys.exit('Sequence must be sorted to apply binary search')
target_input = input_function(
'Enter a single number to be found in the list:\n'

52
bubble_sort.py Normal file
View File

@ -0,0 +1,52 @@
"""
This is pure python implementation of bubble sort algorithm
For doctests run following command:
python -m doctest -v bubble_sort.py
or
python3 -m doctest -v bubble_sort.py
For manual testing run:
python bubble_sort.py
"""
from __future__ import print_function
def bubble_sort(collection):
"""Pure implementation of bubble sort algorithm in Python
:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending
Examples:
>>> bubble_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> bubble_sort([])
[]
>>> bubble_sort([-2, -5, -45])
[-45, -5, -2]
"""
length = len(collection)
for i in range(length):
for j in range(length-1):
if collection[j] > collection[j+1]:
collection[j], collection[j+1] = collection[j+1], collection[j]
return collection
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
# otherwise 2.x's input builtin function is too "smart"
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
user_input = input_function('Enter numbers separated by coma:\n')
unsorted = [int(item) for item in user_input.split(',')]
print(bubble_sort(unsorted))

56
insertion_sort.py Normal file
View File

@ -0,0 +1,56 @@
"""
This is pure python implementation of insertion sort algorithm
For doctests run following command:
python -m doctest -v insertion_sort.py
or
python3 -m doctest -v insertion_sort.py
For manual testing run:
python insertion_sort.py
"""
from __future__ import print_function
def insertion_sort(collection):
"""Pure implementation of insertion sort algorithm in Python
:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending
Examples:
>>> insertion_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> insertion_sort([])
[]
>>> insertion_sort([-2, -5, -45])
[-45, -5, -2]
"""
length = len(collection)
for i in range(length):
current_item = collection[i]
j = i - 1
while j >= 0 and current_item < collection[j]:
collection[j+1] = collection[j]
j -= 1
collection[j+1] = current_item
return collection
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
# otherwise 2.x's input builtin function is too "smart"
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
user_input = input_function('Enter numbers separated by coma:\n')
unsorted = [int(item) for item in user_input.split(',')]
print(insertion_sort(unsorted))

62
linear_search.py Normal file
View File

@ -0,0 +1,62 @@
"""
This is pure python implementation of linear search algorithm
For doctests run following command:
python -m doctest -v linear_search.py
or
python3 -m doctest -v linear_search.py
For manual testing run:
python linear_search.py
"""
from __future__ import print_function
def linear_search(sequence, target):
"""Pure implementation of binary search algorithm in Python
:param sequence: some sorted collection with comparable items
:param target: item value to search
:return: index of found item or None if item is not found
Examples:
>>> linear_search([0, 5, 7, 10, 15], 0)
0
>>> linear_search([0, 5, 7, 10, 15], 15)
4
>>> linear_search([0, 5, 7, 10, 15], 5)
1
>>> linear_search([0, 5, 7, 10, 15], 6)
"""
for index, item in enumerate(sequence):
if item == target:
return index
return None
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
# otherwise 2.x's input builtin function is too "smart"
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
user_input = input_function('Enter numbers separated by coma:\n')
sequence = [int(item) for item in user_input.split(',')]
target_input = input_function(
'Enter a single number to be found in the list:\n'
)
target = int(target_input)
result = linear_search(sequence, target)
if result is not None:
print('{} found at positions: {}'.format(target, result))
else:
print('Not found')

76
merge_sort.py Normal file
View File

@ -0,0 +1,76 @@
"""
This is pure python implementation of merge sort algorithm
For doctests run following command:
python -m doctest -v merge_sort.py
or
python3 -m doctest -v merge_sort.py
For manual testing run:
python merge_sort.py
"""
from __future__ import print_function
def merge_sort(collection):
"""Pure implementation of merge sort algorithm in Python
:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending
Examples:
>>> merge_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> merge_sort([])
[]
>>> merge_sort([-2, -5, -45])
[-45, -5, -2]
"""
length = len(collection)
if length > 1:
midpoint = length // 2
left_half = merge_sort(collection[:midpoint])
right_half = merge_sort(collection[midpoint:])
i = 0
j = 0
k = 0
left_length = len(left_half)
right_length = len(right_half)
while i < left_length and j < right_length:
if left_half[i] < right_half[j]:
collection[k] = left_half[i]
i += 1
else:
collection[k] = right_half[j]
j += 1
k += 1
while i < left_length:
collection[k] = left_half[i]
i += 1
k += 1
while j < right_length:
collection[k] = right_half[j]
j += 1
k += 1
return collection
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
# otherwise 2.x's input builtin function is too "smart"
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
user_input = input_function('Enter numbers separated by coma:\n')
unsorted = [int(item) for item in user_input.split(',')]
print(merge_sort(unsorted))

61
quick_sort.py Normal file
View File

@ -0,0 +1,61 @@
"""
This is pure python implementation of quick sort algorithm
For doctests run following command:
python -m doctest -v quick_sort.py
or
python3 -m doctest -v quick_sort.py
For manual testing run:
python quick_sort.py
"""
from __future__ import print_function
def quick_sort(collection):
"""Pure implementation of quick sort algorithm in Python
:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending
Examples:
>>> quick_sort([0, 5, 3, 2, 2])
[0, 2, 2, 3, 5]
>>> quick_sort([])
[]
>>> quick_sort([-2, -5, -45])
[-45, -5, -2]
"""
less = []
equal = []
greater = []
if len(collection) > 1:
pivot = collection[0]
for x in collection:
if x < pivot:
less.append(x)
if x == pivot:
equal.append(x)
if x > pivot:
greater.append(x)
return quick_sort(less) + equal + quick_sort(greater)
else:
return collection
if __name__ == '__main__':
import sys
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
# otherwise 2.x's input builtin function is too "smart"
if sys.version_info.major < 3:
input_function = raw_input
else:
input_function = input
user_input = input_function('Enter numbers separated by coma:\n')
unsorted = [int(item) for item in user_input.split(',')]
print(quick_sort(unsorted))

View File

@ -5,10 +5,14 @@ For doctests run following command:
python -m doctest -v selection_sort.py
or
python3 -m doctest -v selection_sort.py
For manual testing run:
python selection_sort.py
"""
from __future__ import print_function
def selection_sort(sortable):
def selection_sort(collection):
"""Pure implementation of selection sort algorithm in Python
Examples:
@ -21,20 +25,20 @@ def selection_sort(sortable):
>>> selection_sort([-2, -5, -45])
[-45, -5, -2]
:param sortable: some mutable ordered collection with heterogeneous
:param collection: some mutable ordered collection with heterogeneous
comparable items inside
:return: the same collection ordered by ascending
"""
length = len(sortable)
length = len(collection)
for i in range(length):
least = i
for k in range(i + 1, length):
if sortable[k] < sortable[least]:
if collection[k] < collection[least]:
least = k
sortable[least], sortable[i] = (
sortable[i], sortable[least]
collection[least], collection[i] = (
collection[i], collection[least]
)
return sortable
return collection
if __name__ == '__main__':