mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-04-29 20:26:07 -04:00
Add some cool queue, stacks, strings, math, bit manipulation examples (#35)
This commit is contained in:
parent
f3ee2cdf52
commit
0f455a0322
11
README.md
11
README.md
@ -37,17 +37,10 @@
|
|||||||
|
|
||||||
|
|
||||||
* **📖 algorithms and data structures revisited (2023)**:
|
* **📖 algorithms and data structures revisited (2023)**:
|
||||||
* 𝟘𝟘𝟙𝟘. **[arrays, vectors, strings](arrays_and_strings)**
|
* 𝟘𝟘𝟙𝟘. **[arrays and strings](arrays_and_strings)**
|
||||||
* 𝟘𝟘𝟙𝟙. **[linked lists](linked_lists)**
|
* 𝟘𝟘𝟙𝟙. **[linked lists](linked_lists)**
|
||||||
* 𝟘𝟙𝟘𝟘. **[stacks and queues](stacks_and_queues)**
|
* 𝟘𝟙𝟘𝟘. **[stacks and queues](stacks_and_queues)**
|
||||||
* 𝟘𝟙𝟘𝟙. **[bit manipulation](bit_manipulation)**
|
* 𝟘𝟙𝟘𝟙. **[bit manipulation](bit_manipulation)**
|
||||||
* 𝟘𝟙𝟙𝟘. **[math and logic](math_and_logic)**
|
* 𝟘𝟙𝟙𝟘. **[math and logic](math_and_logic)**
|
||||||
* 𝟘𝟙𝟙𝟙. **[object-oriented design](object_oriented_design)**
|
|
||||||
* 𝟙𝟘𝟘𝟘. **[recursion and dynamic programming](recursion_and_dp)**
|
|
||||||
* 𝟙𝟘𝟘𝟙. **[sorting and searching](sorting_and_searching)**
|
* 𝟙𝟘𝟘𝟙. **[sorting and searching](sorting_and_searching)**
|
||||||
* 𝟙𝟘𝟙𝟘. **[concurrency](concurrency)**
|
* 𝟙𝟘𝟙𝟙. **[trees, transversals, graphs](trees_and_graphs/)**
|
||||||
* 𝟙𝟘𝟙𝟙. **[trees and graphs](trees_and_graphs/)**
|
|
||||||
- [trees, nodes, binary trees, binary search, trees](trees_and_graphs/Trees.py)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
## arrays and strings
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `is_palindrome.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 is_palindrome.py
|
||||||
|
|
||||||
|
Testing is_palindrome()...
|
||||||
|
Is subi no onibus a palindrone?: True
|
||||||
|
Is helllo there a palindrone?: False
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `playing_with_strings.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 playing_with_strings.py
|
||||||
|
|
||||||
|
Testing reverse_array_in_place
|
||||||
|
Array: [1, 2, 3, 4, 5]
|
||||||
|
Reversed: [5, 4, 3, 2, 1]
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `anagram.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 anagram.py
|
||||||
|
|
||||||
|
Testing is_anagram()...
|
||||||
|
Is listen an anagram of silent?: True
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `permutation.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 permutation.py
|
||||||
|
|
||||||
|
Testing permutation()...
|
||||||
|
Permutation of bt3gl: ['bt3gl', 'bt3lg', 'btg3l', 'btgl3', 'btl3g', 'btlg3', 'b3tgl', 'b3tlg', 'b3gtl', 'b3glt', 'b3ltg', 'b3lgt', 'bgt3l', 'bgtl3', 'bg3tl', 'bg3lt', 'bglt3', 'bgl3t', 'blt3g', 'bltg3', 'bl3tg', 'bl3gt', 'blgt3', 'blg3t', 'tb3gl', 'tb3lg', 'tbg3l', 'tbgl3', 'tbl3g', 'tblg3', 't3bgl', 't3blg', 't3gbl', 't3glb', 't3lbg', 't3lgb', 'tgb3l', 'tgbl3', 'tg3bl', 'tg3lb', 'tglb3', 'tgl3b', 'tlb3g', 'tlbg3', 'tl3bg', 'tl3gb', 'tlgb3', 'tlg3b', '3btgl', '3btlg', '3bgtl', '3bglt', '3bltg', '3blgt', '3tbgl', '3tblg', '3tgbl', '3tglb', '3tlbg', '3tlgb', '3gbtl', '3gblt', '3gtbl', '3gtlb', '3glbt', '3gltb', '3lbtg', '3lbgt', '3ltbg', '3ltgb', '3lgbt', '3lgtb', 'gbt3l', 'gbtl3', 'gb3tl', 'gb3lt', 'gblt3', 'gbl3t', 'gtb3l', 'gtbl3', 'gt3bl', 'gt3lb', 'gtlb3', 'gtl3b', 'g3btl', 'g3blt', 'g3tbl', 'g3tlb', 'g3lbt', 'g3ltb', 'glbt3', 'glb3t', 'gltb3', 'glt3b', 'gl3bt', 'gl3tb', 'lbt3g', 'lbtg3', 'lb3tg', 'lb3gt', 'lbgt3', 'lbg3t', 'ltb3g', 'ltbg3', 'lt3bg', 'lt3gb', 'ltgb3', 'ltg3b', 'l3btg', 'l3bgt', 'l3tbg', 'l3tgb', 'l3gbt', 'l3gtb', 'lgbt3', 'lgb3t', 'lgtb3', 'lgt3b', 'lg3bt', 'lg3tb']
|
||||||
|
```
|
26
arrays_and_strings/anagram.py
Normal file
26
arrays_and_strings/anagram.py
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
def is_anagram(string1, string2) -> bool:
|
||||||
|
|
||||||
|
string1 = string1.lower()
|
||||||
|
string2 = string2.lower()
|
||||||
|
|
||||||
|
if len(string1) != len(string2):
|
||||||
|
return False
|
||||||
|
|
||||||
|
for char in string1:
|
||||||
|
if char not in string2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
print('Testing is_anagram()...')
|
||||||
|
string1 = "listen"
|
||||||
|
string2 = "silent"
|
||||||
|
print(f'Is {string1} an anagram of {string2}?: {is_anagram(string1, string2)}')
|
23
arrays_and_strings/palindrome.py
Normal file
23
arrays_and_strings/palindrome.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
def is_palindrome(sentence):
|
||||||
|
|
||||||
|
sentence = sentence.strip(' ')
|
||||||
|
if len(sentence) < 2:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if sentence[0] == sentence[-1]:
|
||||||
|
return is_palindrome(sentence[1:-1])
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print('Testing is_palindrome()...')
|
||||||
|
sentence ="subi no onibus"
|
||||||
|
print(f'Is {sentence} a palindrone?: {is_palindrome(sentence)}')
|
||||||
|
|
||||||
|
sentence ="helllo there"
|
||||||
|
print(f'Is {sentence} a palindrone?: {is_palindrome(sentence)}')
|
22
arrays_and_strings/permutation.py
Normal file
22
arrays_and_strings/permutation.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
def permutation(string) -> list:
|
||||||
|
|
||||||
|
if len(string) == 1:
|
||||||
|
return [string]
|
||||||
|
|
||||||
|
result = []
|
||||||
|
for i, char in enumerate(string):
|
||||||
|
for perm in permutation(string[:i] + string[i+1:]):
|
||||||
|
result += [char + perm]
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print('Testing permutation()...')
|
||||||
|
string = "bt3gl"
|
||||||
|
print(f'Permutation of {string}: {permutation(string)}')
|
15
arrays_and_strings/playing_with_strings.py
Normal file
15
arrays_and_strings/playing_with_strings.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
def reverse_array_in_place(array):
|
||||||
|
""" Reverse an array in place """
|
||||||
|
return array[::-1]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
print('Testing reverse_array_in_place')
|
||||||
|
array = [1, 2, 3, 4, 5]
|
||||||
|
print(f'Array: {array}')
|
||||||
|
print(f'Reversed: {reverse_array_in_place(array)}')
|
@ -0,0 +1,25 @@
|
|||||||
|
## bit manipulation
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `playing_with_bits.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python3 playing_with_bits.py
|
||||||
|
|
||||||
|
Integer number: 144
|
||||||
|
Binary number: 10010000
|
||||||
|
|
||||||
|
Update bit: 0b10010100
|
||||||
|
Set bit: 0b10010100
|
||||||
|
Clear bit: 0b10000000
|
||||||
|
|
||||||
|
I: 144, I2: 90
|
||||||
|
B: 10010000, B2: 01011010
|
||||||
|
Count bits swapped: 4
|
||||||
|
|
||||||
|
Swap bit in place: (90, 144)
|
||||||
|
```
|
59
bit_manipulation/playing_with_bits.py
Normal file
59
bit_manipulation/playing_with_bits.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
def set_bit(num, i):
|
||||||
|
mask = 1 << i
|
||||||
|
return bin( num | mask )
|
||||||
|
|
||||||
|
def update_bit(num, i, v):
|
||||||
|
mask = ~ (1 << i)
|
||||||
|
return bin( (num & mask) | (v << i) )
|
||||||
|
|
||||||
|
def count_bits_swapped(a, b):
|
||||||
|
count = 0
|
||||||
|
m = a^b
|
||||||
|
while m:
|
||||||
|
count +=1
|
||||||
|
m = m & (m-1)
|
||||||
|
return count
|
||||||
|
|
||||||
|
def clear_bit(num, i):
|
||||||
|
mask = ~ (1 << i) # -0b10001
|
||||||
|
return bin(num & mask)
|
||||||
|
|
||||||
|
def swap_bit_in_place(a, b):
|
||||||
|
a = a^b
|
||||||
|
b = a^b
|
||||||
|
a = a^b
|
||||||
|
return a, b
|
||||||
|
|
||||||
|
def find_how_many_1_in_a_binary(num):
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
while num:
|
||||||
|
if num & 1:
|
||||||
|
counter += 1
|
||||||
|
num >>= 1
|
||||||
|
return counter
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
binary_number = '10010000'
|
||||||
|
binary_number2 = '01011010'
|
||||||
|
integer_number = int(binary_number, 2)
|
||||||
|
integer_number2 = int(binary_number2, 2)
|
||||||
|
|
||||||
|
print(f'Integer number: {integer_number}')
|
||||||
|
print(f'Binary number: {binary_number}')
|
||||||
|
print(f'\nUpdate bit: {update_bit(integer_number, 2, 1)}')
|
||||||
|
print(f'Set bit: {set_bit(integer_number, 2)}')
|
||||||
|
print(f'Clear bit: {clear_bit(integer_number, 4)}')
|
||||||
|
print(f'\nI: {integer_number}, I2: {integer_number2}')
|
||||||
|
print(f'B: {binary_number}, B2: {binary_number2}')
|
||||||
|
print(f'Count bits swapped: {count_bits_swapped(integer_number, integer_number2)}')
|
||||||
|
print(f'\nSwap bit in place: {swap_bit_in_place(integer_number, integer_number2)}')
|
||||||
|
print(f'Find how many 1 in a binary: {find_how_many_1_in_a_binary(integer_number)}')
|
||||||
|
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
__author__ = "bt3"
|
__author__ = "bt3"
|
||||||
|
|
||||||
def binary_serch_counting(lst1, k, lo=0, hi=None):
|
def binary_search_counting(lst1, k, lo=0, hi=None):
|
||||||
if hi is None: hi = len(lst1)
|
if hi is None: hi = len(lst1)
|
||||||
while lo < hi:
|
while lo < hi:
|
||||||
mid = (lo+hi)//2
|
mid = (lo+hi)//2
|
||||||
@ -24,7 +24,7 @@ def find_time_occurrence_list(seq, k):
|
|||||||
the dict is fixed. Another way, since the array is sorted, it to
|
the dict is fixed. Another way, since the array is sorted, it to
|
||||||
use binary search, since this is only O(logn).
|
use binary search, since this is only O(logn).
|
||||||
"""
|
"""
|
||||||
index_some_k = binary_serch_counting(seq, k)
|
index_some_k = binary_search_counting(seq, k)
|
||||||
count = 1
|
count = 1
|
||||||
sizet = len(seq)
|
sizet = len(seq)
|
||||||
|
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
## math and logic
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 fibonacci.py
|
||||||
|
|
||||||
|
Testing fibonacci
|
||||||
|
Fibonacci of 10: 55
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python playing_with_math.py
|
||||||
|
|
||||||
|
Greatest common divider of 21 and 7 is 7
|
||||||
|
Prime factors of 21 are [3, 7]
|
||||||
|
```
|
16
math_and_logic/fibonacci.py
Normal file
16
math_and_logic/fibonacci.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
def fibonacci(n):
|
||||||
|
""" Calculate the nth Fibonacci number """
|
||||||
|
if n == 0 or n == 1:
|
||||||
|
return n
|
||||||
|
return fibonacci(n - 1) + fibonacci(n - 2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
print('Testing fibonacci')
|
||||||
|
n = 10
|
||||||
|
print(f'Fibonacci of {n}: {fibonacci(n)}')
|
50
math_and_logic/playing_with_math.py
Normal file
50
math_and_logic/playing_with_math.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
def find_greatest_common_divider(a, b) -> int:
|
||||||
|
'''Implements the greatest common divider algorithm '''
|
||||||
|
|
||||||
|
while(b != 0):
|
||||||
|
result = b
|
||||||
|
a, b = b, a % b
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def _is_prime(number) -> bool:
|
||||||
|
'''Check if a number is prime '''
|
||||||
|
|
||||||
|
if number < 2:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for i in range(2, int(math.sqrt(number))):
|
||||||
|
if number % i == 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def find_prime_factors(number) -> list:
|
||||||
|
'''Find prime factors of a number '''
|
||||||
|
|
||||||
|
divisors = [d for d in range(2, number//2 + 1) if number % d == 0]
|
||||||
|
primes = [d for d in divisors if _is_prime(d)]
|
||||||
|
|
||||||
|
return primes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
n1 = 21
|
||||||
|
n2 = 7
|
||||||
|
|
||||||
|
print(f'Greatest common divider of {n1} and {n2} is {find_greatest_common_divider(n1, n2)}')
|
||||||
|
print(f'Prime factors of {n1} are {find_prime_factors(n1)}')
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
## sorting and searching
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `sorting_algorithms.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python3 sorting_algorithms.py
|
||||||
|
|
||||||
|
|
||||||
|
Array: [3, 5, 1, 2, 10, 6]
|
||||||
|
Testing merge sort: [1, 2, 3, 5, 6, 10]
|
||||||
|
Testing quick sort: [1, 2, 3, 5, 6, 10]
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `binary_search.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python binary_search.py
|
||||||
|
Recursive: 6
|
||||||
|
Iterative: 6
|
||||||
|
```
|
||||||
|
|
68
sorting_and_searching/binary_search.py
Normal file
68
sorting_and_searching/binary_search.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
def binary_search_recursive(array, item, higher=None, lower=0):
|
||||||
|
|
||||||
|
higher = higher or len(array)
|
||||||
|
if higher < lower:
|
||||||
|
return False
|
||||||
|
|
||||||
|
mid = (higher + lower)//2
|
||||||
|
if item == array[mid]:
|
||||||
|
return mid
|
||||||
|
elif item < array[mid]:
|
||||||
|
return binary_search_recursive(array, item, higher=mid-1, lower=lower)
|
||||||
|
else:
|
||||||
|
return binary_search_recursive(array, item, higher=higher, lower=mid+1)
|
||||||
|
|
||||||
|
|
||||||
|
def binary_search_iterative(array, item):
|
||||||
|
lower, higher = 0, len(array)
|
||||||
|
|
||||||
|
while lower < higher:
|
||||||
|
mid = (higher+lower)//2
|
||||||
|
if array[mid] == item:
|
||||||
|
return mid
|
||||||
|
elif array[mid] > item:
|
||||||
|
higher = mid
|
||||||
|
else:
|
||||||
|
lower=mid+1
|
||||||
|
return False
|
||||||
|
|
||||||
|
def binary_search_matrix(matrix, item, lower=0, higher=None):
|
||||||
|
""" Binary search in a matrix """
|
||||||
|
|
||||||
|
if not matrix:
|
||||||
|
return None
|
||||||
|
|
||||||
|
rows = len(matrix)
|
||||||
|
cols = len(matrix[0])
|
||||||
|
higher = higher or rows*cols
|
||||||
|
|
||||||
|
if higher > lower:
|
||||||
|
mid = (higher + lower)//2
|
||||||
|
row = mid//cols
|
||||||
|
col = mid%cols
|
||||||
|
item = matrix[row][col]
|
||||||
|
|
||||||
|
if item == item:
|
||||||
|
return row, col
|
||||||
|
elif item < item:
|
||||||
|
return binary_search_matrix(matrix, item, lower, mid-1)
|
||||||
|
else:
|
||||||
|
return binary_search_matrix(matrix, item, mid+1, higher)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
array = [2, 3, 5, 6, 8, 10, 15, 23]
|
||||||
|
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
||||||
|
item = 15
|
||||||
|
|
||||||
|
print('Recursive: ', binary_search_recursive(array, item))
|
||||||
|
print('Iterative: ', binary_search_iterative(array, item))
|
||||||
|
print('Matrix: ', binary_search_matrix(matrix, item))
|
||||||
|
|
64
sorting_and_searching/sorting_algorithms.py
Normal file
64
sorting_and_searching/sorting_algorithms.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
def merge_sort(array):
|
||||||
|
"""Sort an array using merge sort"""
|
||||||
|
|
||||||
|
# part 1: recursively divide the array into subarrays
|
||||||
|
if len(array) < 2:
|
||||||
|
return array
|
||||||
|
|
||||||
|
mid = len(array) // 2
|
||||||
|
left = merge_sort(array[:mid])
|
||||||
|
right = merge_sort(array[mid:])
|
||||||
|
|
||||||
|
# part 2: merge the subarrays
|
||||||
|
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:])
|
||||||
|
if right[j:]:
|
||||||
|
result.extend(right[j:])
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def quick_sort_partition(array):
|
||||||
|
"""Sort an array using quick sort"""
|
||||||
|
|
||||||
|
pivot, array = array[0], array[1:]
|
||||||
|
|
||||||
|
lower = [i for i in array if i <= pivot]
|
||||||
|
higher = [i for i in array if i > pivot]
|
||||||
|
|
||||||
|
return lower, pivot, higher
|
||||||
|
|
||||||
|
|
||||||
|
def quick_sort_divided(array):
|
||||||
|
"""Sort an array using quick sort"""
|
||||||
|
|
||||||
|
if len(array) < 2:
|
||||||
|
return array
|
||||||
|
|
||||||
|
lower, pivot, higher = quick_sort_partition(array)
|
||||||
|
return quick_sort_divided(lower) + [pivot] + quick_sort_divided(higher)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
array = [3, 5, 1, 2, 10, 6]
|
||||||
|
print(f'Array: {array}')
|
||||||
|
|
||||||
|
print(f'Testing merge sort: {merge_sort(array)}')
|
||||||
|
print(f'Testing quick sort: {quick_sort_divided(array)}')
|
120
stacks_and_queues/Queue.py
Normal file
120
stacks_and_queues/Queue.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
import heapq
|
||||||
|
|
||||||
|
|
||||||
|
class Queue:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self._in = []
|
||||||
|
self._out = []
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Private methods
|
||||||
|
######################
|
||||||
|
def _transfer_in_to_out(self):
|
||||||
|
while self._in:
|
||||||
|
self._out.append(self._in.pop())
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if not self._out:
|
||||||
|
self._transfer_in_to_out()
|
||||||
|
|
||||||
|
return f'{self._out}'
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Properties
|
||||||
|
######################
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
return len(self._in) + len(self._out)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def peek(self):
|
||||||
|
if not self._out:
|
||||||
|
self._transfer_in_to_out()
|
||||||
|
if self._out:
|
||||||
|
return self._out[-1]
|
||||||
|
else:
|
||||||
|
print('❌ Queue is empty, cannot peek.')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_empty(self):
|
||||||
|
return not (bool(self._in) or bool(self._out))
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Public methods
|
||||||
|
######################
|
||||||
|
def enqueue(self, item):
|
||||||
|
self._in.append(item)
|
||||||
|
|
||||||
|
def dequeue(self):
|
||||||
|
if not self._out:
|
||||||
|
while self._in:
|
||||||
|
self.out.append(self._in.pop())
|
||||||
|
|
||||||
|
if self._out:
|
||||||
|
self._out.pop()
|
||||||
|
else:
|
||||||
|
print('❌ Queue is empty, cannot dequeue.')
|
||||||
|
|
||||||
|
|
||||||
|
class PriorityQueue:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.queue = []
|
||||||
|
self.index = 0
|
||||||
|
|
||||||
|
def push(self, item, priority):
|
||||||
|
heapq.heappush(self.queue, (-priority, self.index, item))
|
||||||
|
self.index += 1
|
||||||
|
|
||||||
|
def pop(self):
|
||||||
|
return heapq.heappop(self.queue)[-1]
|
||||||
|
|
||||||
|
class Item:
|
||||||
|
|
||||||
|
def __init__(self, name):
|
||||||
|
self.name = name
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'{self.name}'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Simple Queue
|
||||||
|
######################
|
||||||
|
print('🧪 Testing Queue...')
|
||||||
|
queue = Queue()
|
||||||
|
print(f"Is the queue empty? {queue.is_empty}")
|
||||||
|
print("Adding 1 to 10 in the queue...")
|
||||||
|
for i in range(1, 11):
|
||||||
|
queue.enqueue(i)
|
||||||
|
|
||||||
|
print(f"Queue: {queue}")
|
||||||
|
print(f"\nQueue size: {queue.size}")
|
||||||
|
print(f"Queue peek : {queue.peek}")
|
||||||
|
print(f"Is the queue empty? {queue.is_empty}")
|
||||||
|
print(f"\nDequeue...")
|
||||||
|
queue.dequeue()
|
||||||
|
print(f"Queue: {queue}")
|
||||||
|
print(f"\nQueue size: {queue.size}")
|
||||||
|
print(f"Queue peek: {queue.peek}")
|
||||||
|
print(f"Is the queue empty? {queue.is_empty}")
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Priority Queue
|
||||||
|
######################
|
||||||
|
print('\n\n🧪 Testing Priority Queue...')
|
||||||
|
q = PriorityQueue()
|
||||||
|
q.push(Item('Item 1'), 1)
|
||||||
|
q.push(Item('Item 4'), 4)
|
||||||
|
q.push(Item('Item 3'), 3)
|
||||||
|
print(f"Priority Queue: {q.queue}")
|
||||||
|
print(f"Pop: {q.pop()}")
|
||||||
|
print(f"Priority Queue: {q.queue}")
|
@ -0,0 +1,59 @@
|
|||||||
|
## stacks and queues
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `Queues.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python3 queues.py
|
||||||
|
|
||||||
|
🧪 Testing Queue...
|
||||||
|
Is the queue empty? True
|
||||||
|
Adding 1 to 10 in the queue...
|
||||||
|
Queue: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
|
||||||
|
|
||||||
|
Queue size: 10
|
||||||
|
Queue peek : 1
|
||||||
|
Is the queue empty? False
|
||||||
|
|
||||||
|
Dequeue...
|
||||||
|
Queue: [10, 9, 8, 7, 6, 5, 4, 3, 2]
|
||||||
|
|
||||||
|
Queue size: 9
|
||||||
|
Queue peek: 2
|
||||||
|
Is the queue empty? False
|
||||||
|
|
||||||
|
|
||||||
|
🧪 Testing Priority Queue...
|
||||||
|
Priority Queue: [(-4, 1, Item 4), (-1, 0, Item 1), (-3, 2, Item 3)]
|
||||||
|
Pop: Item 4
|
||||||
|
Priority Queue: [(-3, 2, Item 3), (-1, 0, Item 1)]
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `stack.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
python3 stack.py
|
||||||
|
|
||||||
|
Testing Stack...
|
||||||
|
|
||||||
|
Stack: [12, 13, 14, 15, 16, 17, 18, 19, 20]
|
||||||
|
Stack size: 9
|
||||||
|
Stack peek: 20
|
||||||
|
Stack is empty: False
|
||||||
|
Stack min: 12
|
||||||
|
|
||||||
|
Popping...
|
||||||
|
20
|
||||||
|
19
|
||||||
|
18
|
||||||
|
17
|
||||||
|
16
|
||||||
|
Stack: [12, 13, 14, 15]
|
||||||
|
```
|
79
stacks_and_queues/Stack.py
Normal file
79
stacks_and_queues/Stack.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
class Stack:
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.content = []
|
||||||
|
self.min_array = []
|
||||||
|
self.min = float('inf')
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Private methods
|
||||||
|
######################
|
||||||
|
def __repr__(self):
|
||||||
|
return f'{self.content}'
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Properties
|
||||||
|
######################
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
return len(self.content)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def peek(self):
|
||||||
|
if self.content:
|
||||||
|
return self.content[-1]
|
||||||
|
else:
|
||||||
|
print('❌ Queue is empty, cannot peek.')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_empty(self):
|
||||||
|
return not bool(self.content)
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Public methods
|
||||||
|
######################
|
||||||
|
def push(self, value):
|
||||||
|
if value < self.min:
|
||||||
|
self.min = value
|
||||||
|
|
||||||
|
self.content.append(value)
|
||||||
|
self.min_array.append(self.min)
|
||||||
|
|
||||||
|
def pop(self):
|
||||||
|
if self.content:
|
||||||
|
value = self.content.pop()
|
||||||
|
self.min_array.pop()
|
||||||
|
if self.min_array:
|
||||||
|
self.min = self.min_array[-1]
|
||||||
|
return value
|
||||||
|
|
||||||
|
def find_min(self):
|
||||||
|
if self.min_array:
|
||||||
|
return self.min_array[-1]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
######################
|
||||||
|
# Simple Stack
|
||||||
|
######################
|
||||||
|
print('Testing Stack...')
|
||||||
|
stack = Stack()
|
||||||
|
for i in range(12, 21):
|
||||||
|
stack.push(i)
|
||||||
|
|
||||||
|
print(f'\nStack: {stack}')
|
||||||
|
print(f'Stack size: {stack.size}')
|
||||||
|
print(f'Stack peek: {stack.peek}')
|
||||||
|
print(f'Stack is empty: {stack.is_empty}')
|
||||||
|
print(f'Stack min: {stack.find_min()}')
|
||||||
|
|
||||||
|
print('\nPopping...')
|
||||||
|
for i in range(5):
|
||||||
|
print(stack.pop())
|
||||||
|
print(f'Stack: {stack}')
|
105
trees_and_graphs/BinaryTree.py
Normal file
105
trees_and_graphs/BinaryTree.py
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# author: bt3gl
|
||||||
|
|
||||||
|
|
||||||
|
class Node(object):
|
||||||
|
|
||||||
|
def __init__(self, value):
|
||||||
|
self.value = value
|
||||||
|
self.right = None
|
||||||
|
self.left = None
|
||||||
|
|
||||||
|
def add(self, value):
|
||||||
|
new_node = Node(value)
|
||||||
|
if not self.value:
|
||||||
|
self.value = new_node
|
||||||
|
elif not self.left:
|
||||||
|
self.left = new_node
|
||||||
|
elif not self. right:
|
||||||
|
self.right = new_node
|
||||||
|
else:
|
||||||
|
self.left = self.left.add(value)
|
||||||
|
return self # without this, it doesn't add!
|
||||||
|
|
||||||
|
def search(self, item):
|
||||||
|
if self.value == item:
|
||||||
|
return True
|
||||||
|
found = False
|
||||||
|
if (self.left and self.left.search(item)) or \
|
||||||
|
(self.right and self.right.search(item)):
|
||||||
|
found = True
|
||||||
|
return found
|
||||||
|
|
||||||
|
def preorder(self):
|
||||||
|
yield self.value
|
||||||
|
if self.left:
|
||||||
|
for node in self.left.preorder():
|
||||||
|
yield node
|
||||||
|
if self.right:
|
||||||
|
for node in self.right.preorder():
|
||||||
|
yield node
|
||||||
|
|
||||||
|
def postorder(self):
|
||||||
|
yield self.value
|
||||||
|
if self.left:
|
||||||
|
for node in self.left.postorder():
|
||||||
|
yield node
|
||||||
|
if self.right:
|
||||||
|
for node in self.right.postorder():
|
||||||
|
yield node
|
||||||
|
|
||||||
|
def inorder(self):
|
||||||
|
yield self.value
|
||||||
|
if self.left:
|
||||||
|
for node in self.left.inorder():
|
||||||
|
yield node
|
||||||
|
if self.right:
|
||||||
|
for node in self.right.inorder():
|
||||||
|
yield node
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryTree(object):
|
||||||
|
def __init__(self):
|
||||||
|
self.root = None
|
||||||
|
|
||||||
|
def add(self, value):
|
||||||
|
if not self.root:
|
||||||
|
self.root = Node(value)
|
||||||
|
else:
|
||||||
|
self.root.add(value)
|
||||||
|
|
||||||
|
def search(self, item):
|
||||||
|
if self.root:
|
||||||
|
return self.root.search(item)
|
||||||
|
|
||||||
|
def preorder(self):
|
||||||
|
if self.root:
|
||||||
|
return list(self.root.preorder())
|
||||||
|
|
||||||
|
def inorder(self):
|
||||||
|
if self.root:
|
||||||
|
return list(self.root.inorder())
|
||||||
|
|
||||||
|
def postorder(self):
|
||||||
|
if self.root:
|
||||||
|
return list(self.root.postorder())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
|
||||||
|
|
||||||
|
print("\n\n🌳🌳🌳 Testing BinaryTree 🌳🌳🌳")
|
||||||
|
bt = BinaryTree()
|
||||||
|
array1 = [4, 1, 4, 6, 7, 9, 10, 5, 11, 5]
|
||||||
|
print(f'\n🟡 Adding {array1} to the tree...')
|
||||||
|
for i in array1:
|
||||||
|
bt.add(i)
|
||||||
|
print(f"🟢 Print the tree preorder: {bt.preorder()}")
|
||||||
|
print(f"🟢 Print the tree inorder: {bt.inorder()}")
|
||||||
|
print(f"🟢 Print the tree postorder: {bt.postorder()}")
|
||||||
|
|
||||||
|
print(f'\n🟢 Search for node 5: {bt.search(5)}')
|
||||||
|
print(f'❌ Search for node 15: {bt.search(15)}')
|
||||||
|
|
||||||
|
|
93
trees_and_graphs/README.md
Normal file
93
trees_and_graphs/README.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
## trees
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
|
||||||
|
### `Tree.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python3 Trees.py
|
||||||
|
|
||||||
|
|
||||||
|
🌴🌴🌴 Testing SimpleTree 🌴🌴🌴
|
||||||
|
a
|
||||||
|
b
|
||||||
|
d
|
||||||
|
e
|
||||||
|
c
|
||||||
|
h
|
||||||
|
g
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
🌳🌳🌳 Testing BinaryTree 🌳🌳🌳
|
||||||
|
|
||||||
|
🟡 Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree...
|
||||||
|
🟢 Printing the tree in preorder...
|
||||||
|
4
|
||||||
|
1
|
||||||
|
6
|
||||||
|
9
|
||||||
|
5
|
||||||
|
5
|
||||||
|
11
|
||||||
|
10
|
||||||
|
7
|
||||||
|
4
|
||||||
|
|
||||||
|
🟢 Searching for node 5: True
|
||||||
|
❌ Searching for node 15: False
|
||||||
|
❌ Is root a leaf? False
|
||||||
|
🟢 Is root full? True
|
||||||
|
❌ Is the tree balanced? False
|
||||||
|
❌ Is the tree a binary search tree? False
|
||||||
|
|
||||||
|
|
||||||
|
🎄🎄🎄 Testing BinarySearchTree 🎄🎄🎄
|
||||||
|
|
||||||
|
🟡 Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree...
|
||||||
|
❌ Item 4 not added as BSTs do not support repetition.
|
||||||
|
❌ Item 5 not added as BSTs do not support repetition.
|
||||||
|
🟢 Printing the tree in preorder:
|
||||||
|
4
|
||||||
|
1
|
||||||
|
6
|
||||||
|
5
|
||||||
|
7
|
||||||
|
9
|
||||||
|
10
|
||||||
|
11
|
||||||
|
|
||||||
|
🟢 Searching for node 5: True
|
||||||
|
❌ Searching for node 15: False
|
||||||
|
❌ Is root a leaf? False
|
||||||
|
🟢 Is root full? True
|
||||||
|
🟢 Largest node? 11
|
||||||
|
🟢 Smallest node? 1
|
||||||
|
❌ Is the tree balanced? False
|
||||||
|
🟢 Is the tree a binary search tree? True
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
### `BinaryTree.py`
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
* a clean implementation adapted from the class above.
|
||||||
|
|
||||||
|
```python
|
||||||
|
> python3 BinaryTree.py
|
||||||
|
|
||||||
|
🌳🌳🌳 Testing BinaryTree 🌳🌳🌳
|
||||||
|
|
||||||
|
🟡 Adding [4, 1, 4, 6, 7, 9, 10, 5, 11, 5] to the tree...
|
||||||
|
🟢 Print the tree preorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4]
|
||||||
|
🟢 Print the tree inorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4]
|
||||||
|
🟢 Print the tree postorder: [4, 1, 6, 9, 5, 5, 11, 10, 7, 4]
|
||||||
|
|
||||||
|
🟢 Search for node 5: True
|
||||||
|
❌ Search for node 15: False
|
||||||
|
```
|
@ -294,5 +294,3 @@ if __name__ == '__main__':
|
|||||||
print(f'🟢 Smallest node? {bst.smallest_node(bst.root)}')
|
print(f'🟢 Smallest node? {bst.smallest_node(bst.root)}')
|
||||||
print(f'❌ Is the tree balanced? {bst.is_balanced(bst.root)}')
|
print(f'❌ Is the tree balanced? {bst.is_balanced(bst.root)}')
|
||||||
print(f'🟢 Is the tree a binary search tree? {bst.is_binary_search_tree(bst.root)}')
|
print(f'🟢 Is the tree a binary search tree? {bst.is_binary_search_tree(bst.root)}')
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user