├── README.md
├── section-01-essential-python-concepts
├── 01-basic-data-types-in-python.py
├── 02-basic-builtin-functions-in-python.py
└── README.md
├── section-02-basic-prerequisites
├── 01-memory-management-in-python.py
├── 02-abstract-data-types.py
├── 03-time-and-space-complexity.py
└── README.md
└── section-03-recursion
├── 01-recursion-introduction.py
└── 02-tail-recursion-and-head-recursion.py
/README.md:
--------------------------------------------------------------------------------
1 |
Mastering Data Structure and Algorithms Using Python
2 |
3 | **In this repo I will try to cover Abdul Bari Sir's [Mastering Data Structures & Algorithms using C and C++](https://www.udemy.com/course/datastructurescncpp/) course codes in a _Pythonic_ way.**
4 |
5 | **Repository Notes**
6 |
7 | * You must have basic level of python coding knowledge.
8 | * In this repository I only cover coding parts with minimal explanations.
9 | * Detailed explanations I will added in my [LinkedIn](https://www.linkedin.com/in/tssovi/) and [Medium](https://medium.com/@tssovi) as post.
10 |
11 | **Find Further Details In LinkedIn:**
12 | [Mastering DS & Algo Using Python - LinkedIn](http://bit.ly/mastering-ds-algo-using-python-linkedin)
13 |
14 | **Find Further Details In Medium:**
15 | [Mastering DS & Algo Using Python - Medium](http://bit.ly/mastering-ds-algo-using-python-medium)
16 |
17 | ### Repository Content
18 |
19 | **Section 01: Essential Python Concepts**
20 |
21 | > [01 - Basic Data Types In Python](http://bit.ly/2TQQKl3)\
22 | > [02 - Basic Builtin Functions In Python](http://bit.ly/2TRU3s6)
23 |
24 | **Section 02: Basic Prerequisites**
25 |
26 | > [01 - Memory Management In Python](http://bit.ly/3cXj4tn)\
27 | > [02 - Abstract Data Type (ADT)](http://bit.ly/2vnCjLT)\
28 | > [03 - Time and Space Complexity](http://bit.ly/2IQyUs5)
29 |
30 | **Section 03: Recursion**
31 |
32 | > [01 - Recursion Introduction](http://bit.ly/2wZlQ0V)\
33 | > [02 - Tail Recursion and Head Recursion](https://bit.ly/2UA3prA)\
34 | > 03 - Tree Recursion\
35 | > 04 - Indirect Recursion\
36 | > 05 - Nested Recursion\
37 | > 06 - Sum of Natural Number Using Recursion\
38 | > 07 - Factorial Using Recursion\
39 | > 08 - Power Using Recursion\
40 | > 09 - Taylor Series Using Recursion\
41 | > 10 - Taylor Series Using Horner's Rule Recursion\
42 | > 11 - Fibonacci Series Using Recursion - Memorization\
43 | > 12 - nCr Using Recursion\
44 | > 13 - Tower of Hanoi Problem Using Recursion
45 |
46 | **Section 04: Arrays Representations**
47 |
48 | > 01 - Introduction to Array\
49 | > 02 - Declarations of Array\
50 | > 03 - Static vs Dynamic Arrays\
51 | > 04 - How to Increase Array Size\
52 | > 05 - 2D Arrays\
53 | > 06 - Array Representation by Compiler\
54 | > 07 - Row Major Formula for 2D Arrays\
55 | > 08 - Column Major Formula for 2D Arrays\
56 | > 09 - Formulas for nD Arrays\
57 | > 10 - Formulas for 3D Arrays
58 |
59 | **Section 05: Array ADT**
60 |
61 | > 01 - Array ADT\
62 | > 02 - Inserting in an Array\
63 | > 03 - Deleting from Array\
64 | > 04 - Linear Search\
65 | > 05 - Binary Search\
66 | > 06 - Get( ) Set( ) Avg( ) Max( ) functions on Array\
67 | > 07 - Reverse and Shift an Array\
68 | > 08 - Check if Array is Sorted\
69 | > 09 - Merging Arrays\
70 | > 10 - Set operations on Array - Union, Intersection and Difference\
71 | > 11 - Finding Missing Element(s) in an Array\
72 | > 12 - Finding Duplicates in a Sorted Array\
73 | > 13 - Finding Duplicates in Sorted Array Using Hashing\
74 | > 14 - Finding Duplicates in a Unsorted Array\
75 | > 15 - Finding a Pair of Elements with sum K\
76 | > 16 - Finding a Pair of Elements with sum K in Sorted Array\
77 | > 17 - Finding Max and Min in a Single Scan
78 |
79 | **Section 06: Strings**
80 |
81 | > 01 - Introduction to Strings\
82 | > 02 - Finding Length of a String\
83 | > 03 - Changing Case of a String\
84 | > 04 - Counting Words and Vowels in a String\
85 | > 05 - Validating a String\
86 | > 06 - Reversing a String\
87 | > 07 - Comparing Strings and Checking Palindrome\
88 | > 08 - Finding Duplicates in a String\
89 | > 09 - Finding Duplicates in a String Using Bitwise Operations\
90 | > 10 - Checking if 2 Strings are Anagram\
91 | > 11 - Permutation of String
92 |
93 | **Section 07: Matrices**
94 |
95 | > 01 - Diagonal Matrix\
96 | > 02 - Lower Triangular Matrix Row-Major Mapping\
97 | > 03 - Lower Triangular Matrix Column-Major Mapping\
98 | > 04 - Upper Triangular Matrix Row-Major Mapping\
99 | > 05 - Upper Triangular Matrix Column-Major Mapping\
100 | > 06 - Symmetric Matrix\
101 | > 07 - Tri-Diagonal and Tri-Band Matrix\
102 | > 08 - Toeplitz Matrix\
103 | > 09 - Menu Driven Program for Matrices\
104 | > 10 - Menu Driven Program for Matrices Using Functions
105 |
106 | **Section 08: Sparse Matrix and Polynomial Representation**
107 |
108 | > 01 - Sparse Matrix Representation\
109 | > 02 - Array Representation of Sparse Matrix\
110 | > 03 - Addition of Sparse Matrices\
111 | > 04 - Polynomial
112 |
113 | **Section 09: Linked List**
114 |
115 | > 01 - Display Linked List\
116 | > 02 - Recursive Display of Linked List\
117 | > 03 - Counting Nodes in a Linked List\
118 | > 04 - Sum of All Elements in a Linked List\
119 | > 05 - Maximum Element in a Linked List\
120 | > 06 - Searching in a Linked List\
121 | > 07 - Inserting in a Linked List\
122 | > 08 - Creating a Linked List by Inserting at Last\
123 | > 09 - Inserting in a Sorted Linked List\
124 | > 10 - Deleting from Linked List\
125 | > 11 - Check if a Linked List is Sorted\
126 | > 12 - Remove Duplicates from Linked List\
127 | > 13 - Reversing a Linked List\
128 | > 14 - Recursive Reverse for Linked List\
129 | > 15 - Concatenating 2 Linked Lists\
130 | > 16 - Merging 2 Linked Lists\
131 | > 17 - Check for LOOP in Linked List\
132 | > 18 - Circular Linked List\
133 | > 19 - Inserting in a Circular Linked List\
134 | > 20 - Deleting From Circular Linked List\
135 | > 21 - Doubly Linked List\
136 | > 22 - Insert in a Doubly Linked List\
137 | > 23 - Deleting from Doubly Linked List\
138 | > 24 - Reverse a Doubly Linked List\
139 | > 25 - Circular Doubly Linked List\
140 | > 26 - Finding Middle Element of a Linked List\
141 | > 27 - Finding Intersecting point of Two Linked List
142 |
143 | **Section 10: Sparse Matrix and Polynomial Using Linked List**
144 |
145 | > 01 - Sparse Matrix Using Linked List\
146 | > 02 - Polynomial Representation Using Linked List\
147 |
148 | **Section 11: Stack**
149 |
150 | > 01 - Stack Using Array\
151 | > 02 - Stack Using Linked List\
152 | > 03 - Parenthesis Matching\
153 | > 04 - Infix to Postfix Conversion\
154 | > 05 - Associativity and Unary Operators\
155 | > 06 - Infix to Postfix Using Stack Method\
156 | > 07 -Infix to Postfix with Associativity and Parenthesis\
157 | > 08 - Evaluation of Postfix
158 |
159 | **Section 12: Queues**
160 |
161 | > 01 - Implementing Queue Using Array\
162 | > 02 - Circular Queue\
163 | > 03 - Queue Using Linked List\
164 | > 04 - Double Ended Queue Dequeue\
165 | > 05 - Priority Queues\
166 | > 06 - Queue Using 2 Stacks
167 |
168 | **Section 13: Trees**
169 |
170 | > 01 - Binary Tree\
171 | > 02 - n-ary Trees\
172 | > 03 - Linked Representation of Binary Tree\
173 | > 04 - Binary Tree Traversals\
174 | > 05 - Binary Tree Traversal Easy Method\
175 | > 06 - Creating Binary Tree\
176 | > 07 - Preorder Tree Traversal\
177 | > 08 - Inorder Tree Traversals Functions\
178 | > 09 - Iterative Preorder\
179 | > 10 - Iterative Inorder\
180 | > 11 - Level Order Traversal\
181 | > 12 - Generating Tree from Traversals\
182 | > 13 - Height and Count of Binary Tree\
183 | > 14 - Count Leaf Nodes of a Binary Tree
184 |
185 | **Section 14: Binary Search Trees**
186 |
187 | > 01 - Binary Search Trees intro\
188 | > 02 - Searching in a Binary Search Tree\
189 | > 03 - Inserting in a Binary Search Tree\
190 | > 04 - Recursive Insert in Binary Search Tree\
191 | > 05 - Creating a Binary Search Tree\
192 | > 06 - Deleting from Binary Search Tree\
193 | > 07 - Generating Binary Search Trees from Preorder
194 |
195 | **Section 15: AVL Trees**
196 |
197 | > 01 - Introduction to AVL Trees\
198 | > 02 - Inserting in AVL with Rotations\
199 | > 03 - General form of AVL Rotations\
200 | > 04 - Generating AVL Tree\
201 | > 05 - Deletion from AVL Tree with Rotations\
202 | > 06 - Height Analysis of AVL Trees
203 |
204 | **Section 16: Search Trees**
205 |
206 | > 01 - 2-3 Trees\
207 | > 02 - 2-3-4 Trees\
208 | > 03 - Re-Black Trees Introduction\
209 | > 04 - Red-Black Tree creation\
210 | > 05 - Creating Red-Black Tree similar to Creating 2-3-4 Tree\
211 | > 06 - Red-Black Tree Deletion Cases
212 |
213 | **Section 17: Heap**
214 |
215 | > 01 - Introduction to Heap\
216 | > 02 - Inserting in a Heap\
217 | > 03 - Creating a Heap\
218 | > 04 - Deleting from Heap and Heap Sort\
219 | > 05 - Heapify - Faster Method for Creating Heap\
220 | > 06 - Heap as Priority Queue
221 |
222 | **Section 18: Sorting Techniques**
223 |
224 | > 01 - Bubble Sort\
225 | > 02 - Insertion Sort\
226 | > 03 - Selection Sort\
227 | > 04 - Quick Sort\
228 | > 05 - Iterative Merge Sort\
229 | > 06 - Recursive Merge Sort\
230 | > 07 - Count Sort\
231 | > 08 - Bin / Bucket Sort\
232 | > 09 - Radix Sort\
233 | > 10 - Shell Sort
234 |
235 | **Section 19: Hashing Technique**
236 |
237 | > 01 - Introduction to Hashing\
238 | > 02 - Chaining\
239 | > 03 - Linear Probing\
240 | > 04 - Quadratic Probing\
241 | > 05 - Double Hashing\
242 | > 06 - Hash Function Ideas
243 |
244 | **Section 20: Graphs**
245 |
246 | > 01 - Introduction to Graphs\
247 | > 02 - Representation of Undirected Graph\
248 | > 03 - Representation of Directed Graphs\
249 | > 04 - Breadth First Search\
250 | > 05 - Depth First Search\
251 | > 06 - Spanning Trees\
252 | > 07 - Prim's Minimum Cost Spanning Tree\
253 | > 08 - Kruskal's Minimum Cost Spanning Tree\
254 | > 09 - Disjoint Subsets\
255 | > 10 - Kruskal's Program
256 |
--------------------------------------------------------------------------------
/section-01-essential-python-concepts/01-basic-data-types-in-python.py:
--------------------------------------------------------------------------------
1 | # Here a is int
2 | a = 5
3 | print(a, "is of type", type(a))
4 |
5 | # Here a is float
6 | a = 2.0
7 | print(a, "is of type", type(a))
8 |
9 | # Here a is complex
10 | a = 1+2j
11 | print(a, "is of type", type(a))
12 |
13 | # Here a is list
14 | a = [1, 2.2, 'python']
15 | print(a, "is of type", type(a))
16 |
17 | # List is mutable
18 | a = [1, 2.2, 'python']
19 | a[2] = 'list is mutable'
20 | print(a)
21 |
22 | # Here a is tuple
23 | a = (1, 2.2, 'python')
24 | print(a, "is of type", type(a))
25 |
26 | # Tuple is immutable
27 | a = (1, 2.2, 'python')
28 | try:
29 | a[2] = 'tuple is immutable'
30 | except:
31 | print('Tuple is immutable')
32 | print(a)
33 |
34 | # Here a is single string
35 | a = "This is a string"
36 | print(a, "is of type", type(a))
37 |
38 | # Here a is multiline string
39 | a = '''This is a multiline string
40 | Line 1
41 | Line 2'''
42 | print(a, "is of type", type(a))
43 |
44 | # Here a is set
45 | a = {1,2,2,3,3,3}
46 | print(a, "is of type", type(a))
47 |
48 | # Here a is dict
49 | a = {'key1':'value1','key2':'value2'}
50 | print(a, "is of type", type(a))
51 |
52 | person = {"name": "John", "age": 23, "sex": "male"}
53 |
54 | # Here a is frozenset of person dict
55 | a = frozenset(person)
56 | print(a, "is of type", type(a))
57 |
58 | # Here a is boolean
59 | a = True
60 | print(a, "is of type", type(a))
61 |
62 |
--------------------------------------------------------------------------------
/section-01-essential-python-concepts/02-basic-builtin-functions-in-python.py:
--------------------------------------------------------------------------------
1 | # Math related common functions
2 |
3 | # Random integer number
4 | integer = -10
5 | print('Absolute value of -10 is:', abs(integer))
6 |
7 | # Random floating number
8 | floating = -10.33
9 | print('Absolute value of -10.33 is:', abs(floating))
10 |
11 | # Random complex number
12 | complex = (5 - 2j)
13 | print('Magnitude of 5 - 2j is:', abs(complex))
14 |
15 | # divmod() with intiger numbers
16 | print('Divmod of 7 and 2 is:', divmod(7, 2))
17 |
18 | # divmod() with Floats
19 | print('Divmod of 7.5 and 2.5 is:', divmod(7.5, 2.5))
20 |
21 | # Enumerate example
22 | grocery = ['bread', 'milk', 'butter']
23 |
24 | for count, item in enumerate(grocery):
25 | print(count, item)
26 |
27 | # changing default start value
28 | for count, item in enumerate(grocery, 100):
29 | print(count, item)
30 |
31 | # Max value from a list
32 | numbers = [3, 2, 8, 5, 10, 6]
33 | largest_number = max(numbers)
34 |
35 | print("The largest number from numbers list is:", largest_number)
36 |
37 | # Max value from a list
38 | numbers = [3, 2, 8, 5, 10, 6]
39 | smallest_number = min(numbers)
40 |
41 | print("The smallest number from numbers list is:", smallest_number)
42 |
43 | # Power calculation
44 | x = 7
45 | y = 2
46 | z = 5
47 |
48 | print('Power of x & y is:', pow(x, y))
49 | print('Power of x, y & z is:', pow(x, y, z))
50 |
51 | # Round numbers
52 | x = 5.756
53 |
54 | print('Round of x without decimal points is:', round(x))
55 | print('Round of x for 2 decimal points is:', round(x, 2))
56 |
57 | # Sum of a list
58 | numbers = [2.5, 3, 4, -5]
59 |
60 | # start parameter is not provided
61 | numbers_sum = sum(numbers)
62 | print('Sum of all variable in numbers list is:', numbers_sum)
63 |
64 | # start = 10
65 | numbers_sum = sum(numbers, 10)
66 | print('Sum of all variable in numbers list with 10 is:', numbers_sum)
67 |
68 | # Slice to get a substring from the given string
69 | string = 'Python'
70 |
71 | # stop = 3
72 | # contains 0, 1 and 2 indices
73 | slice_object = slice(3)
74 | print('Substing of Python is:', string[slice_object])
75 |
76 | # start = 1, stop = 6, step = 2
77 | # contains 1, 3 and 5 indices
78 | slice_object = slice(1, 6, 2)
79 | print('Substing of Python is:', string[slice_object])
--------------------------------------------------------------------------------
/section-01-essential-python-concepts/README.md:
--------------------------------------------------------------------------------
1 | Section 01: Essential Python Concepts
2 |
3 | **Find Further Details In LinkedIn:**
4 | > [01 - Basic Data Types In Python - LinkedIn](http://bit.ly/3aWDhxQ)\
5 | > [02 - Basic Builtin Functions In Python - LinkedIn](http://bit.ly/3aSxLMD)
6 |
7 | **Find Further Details In Medium:**
8 | > [01 - Basic Data Types In Python - Medium](http://bit.ly/33hFfGp)\
9 | > [02 - Basic Builtin Functions In Python - Medium](http://bit.ly/3aWPgeQ)
--------------------------------------------------------------------------------
/section-02-basic-prerequisites/01-memory-management-in-python.py:
--------------------------------------------------------------------------------
1 | # Instead of adding line1, line2 to text individually, use list and join
2 | # Don’t do this:
3 |
4 | text = 'line1\n'
5 | text += 'line2'
6 | print(text)
7 |
8 | # Better do this
9 | list=['line1', 'line2']
10 | text = '\n'.join(list)
11 | print(text)
12 |
13 | # Don’t use the + operator for concatenation if you can avoid it
14 | # Don’t do this
15 | msg = '+ operator'
16 | full_msg = 'Avoid using the ' + msg + ' for strings'
17 | print(full_msg)
18 |
19 | # Better do this
20 | full_msg = 'Avoid using the %s for strings' % msg
21 | print(full_msg)
22 |
23 | # Or this
24 | full_msg = 'Avoid using the {} for strings'.format(msg)
25 | print(full_msg)
26 |
27 | # Assign a function to a local variable
28 | class MathFunctions():
29 | def sum(a, b):
30 | return a + b
31 |
32 | sum = MathFunctions.sum
33 | a = 5
34 | b = 6
35 |
36 | res = sum(a, b)
37 | print('Summation of a and b is:', res)
38 |
39 | # Use builtin functions and libraries rather than raw codes
40 | # Don’t do this
41 | word_list = ['python', 'is', 'awesome']
42 | new_list = []
43 | for myword in word_list:
44 | new_list.append(myword.upper())
45 | print(new_list)
46 |
47 | # Better do this
48 | new_list = map(str.upper, word_list)
49 |
50 | # Convert map object to tuple to print
51 | print(tuple(new_list))
52 |
--------------------------------------------------------------------------------
/section-02-basic-prerequisites/02-abstract-data-types.py:
--------------------------------------------------------------------------------
1 | # STack ADT
2 | class Stack:
3 | def __init__(self):
4 | self.items = []
5 |
6 | def isEmpty(self):
7 | return self.items == []
8 |
9 | def push(self, item):
10 | self.items.append(item)
11 |
12 | def pop(self):
13 | return self.items.pop()
14 |
15 | def peek(self):
16 | return self.items[len(self.items) - 1]
17 |
18 | def size(self):
19 | return len(self.items)
20 |
21 |
22 | # Queue ADT
23 | class Queue:
24 | def __init__(self):
25 | self.items = []
26 |
27 | def isEmpty(self):
28 | return self.items == []
29 |
30 | def enqueue(self,item):
31 | self.items.append(item)
32 |
33 | def dequeue(self):
34 | return self.items.pop(0)
35 |
36 | def front(self):
37 | return self.items[len(self.items)-1]
38 |
39 | def size(self):
40 | return len(self.items)
41 |
42 |
43 | # STack ADT operation example
44 | s=Stack()
45 |
46 | print('Stack operation examples')
47 | print(s.isEmpty())
48 | s.push(5)
49 | s.push('python')
50 | print(s.peek())
51 | s.push(True)
52 | print(s.size())
53 | print(s.isEmpty())
54 | s.push(11.5)
55 | print(s.pop())
56 | print(s.pop())
57 | print(s.size())
58 |
59 |
60 | # Queue ADT operation example
61 | q=Queue()
62 |
63 | print('Queue operation examples')
64 | print(q.isEmpty())
65 | q.enqueue(5)
66 | q.enqueue('python')
67 | print(q.front())
68 | q.enqueue(True)
69 | print(q.size())
70 | print(q.isEmpty())
71 | q.enqueue(11.5)
72 | print(q.dequeue())
73 | print(q.dequeue())
74 | print(q.size())
--------------------------------------------------------------------------------
/section-02-basic-prerequisites/03-time-and-space-complexity.py:
--------------------------------------------------------------------------------
1 | # Constant Time - O(1)
2 | def get_first(data):
3 | return data[0]
4 |
5 | # Logarithmic Time - O(log n)
6 | def binary_search(alist, item):
7 | if len(alist) == 0:
8 | return False
9 | else:
10 | midpoint = len(alist)//2
11 | if alist[midpoint]==item:
12 | return True
13 | else:
14 | if item arr[j+1]:
61 | arr[j], arr[j+1] = arr[j+1], arr[j]
62 | return arr
63 |
64 |
65 | # Exponential Time - O(2^n)
66 | def fibonacci(n):
67 | if n <= 1:
68 | return n
69 | return fibonacci(n-1) + fibonacci(n-2)
70 |
71 |
72 | # Factorial - O(n!)
73 | def factorial(n):
74 | return 1 if (n == 1 or n == 0) else n * factorial(n - 1)
75 |
76 |
77 | res_data = []
78 | def heap_permutation(data, n):
79 | if n == 1:
80 | res_data.append(data)
81 | return
82 |
83 | for i in range(n):
84 | heap_permutation(data, n - 1)
85 | if n % 2 == 0:
86 | data[i], data[n - 1] = data[n - 1], data[i]
87 | else:
88 | data[0], data[n - 1] = data[n - 1], data[0]
89 | return res_data
90 |
91 |
92 | num_arr = [58, 24, 84, 2, 30, 27, 35, 91, 14, 23, 53, 33, 99, 17, 86]
93 | l = len(num_arr)
94 |
95 | data = [1, 2, 3]
96 | n = len(data)
97 |
98 | sorted_arr = heap_sort(num_arr, l)
99 |
100 | val = get_first(num_arr)
101 | print("Result of get_first func is:", val)
102 |
103 | val = binary_search(sorted_arr, 17)
104 | print("Result of binary_search func is:", val)
105 |
106 | val = linear_search(num_arr, 17)
107 | print("Result of linear_search func is:", val)
108 |
109 | val = heap_sort(num_arr, l)
110 | print("Result of heap_sort func is:", val)
111 |
112 | val = bubble_sort(num_arr, l)
113 | print("Result of bubble_sort func is:", val)
114 |
115 | val = fibonacci(10)
116 | print("Result of fibonacci func is:", val)
117 |
118 | val = factorial(10)
119 | print("Result of factorial func is:", val)
120 |
121 | val = heap_permutation(data, n)
122 | print("Result of heap_permutation func is:", val)
123 |
124 |
--------------------------------------------------------------------------------
/section-02-basic-prerequisites/README.md:
--------------------------------------------------------------------------------
1 | Section 02: Basic Prerequisites
2 |
3 | **Find Further Details In LinkedIn:**
4 | > [01 - Memory Management In Python - LinkedIn](http://bit.ly/2QjcZhn)\
5 | > [02 - Abstract Data Type (ADT) - LinkedIn](http://bit.ly/33hqweD)\
6 | > [03 - Time and Space Complexity - LinkedIn](http://bit.ly/3aZ5KTG)
7 |
8 | **Find Further Details In Medium:**
9 | > [01 - Memory Management In Python - Medium](http://bit.ly/2IMoUjF)\
10 | > [02 - Abstract Data Type (ADT) - Medium](http://bit.ly/39Qapao)\
11 | > [03 - Time and Space Complexity - Medium](http://bit.ly/3cYl9VX)
--------------------------------------------------------------------------------
/section-03-recursion/01-recursion-introduction.py:
--------------------------------------------------------------------------------
1 | def factorial(n):
2 | if n == 1:
3 | return 1
4 | else:
5 | return (n * factorial(n - 1))
6 |
7 |
8 | def print_number_rev(n):
9 | if n > 0:
10 | print(n)
11 | print_number_rev(n - 1)
12 |
13 |
14 | def print_number(n):
15 | if n > 0:
16 | print_number(n - 1)
17 | print(n)
18 |
19 |
20 | num = 5
21 |
22 | print_number_rev(num)
23 | print_number(num)
24 | print("The factorial of", num, "is", factorial(num))
25 |
--------------------------------------------------------------------------------
/section-03-recursion/02-tail-recursion-and-head-recursion.py:
--------------------------------------------------------------------------------
1 | # normal recursive of factorial
2 | def factorial(n):
3 | if n == 0:
4 | return 1
5 | else:
6 | return n * factorial(n - 1)
7 |
8 |
9 | # tail recursive version of factorial
10 | def tail_factorial(n, num=1):
11 | if n == 0:
12 | return num
13 | else:
14 | return tail_factorial(n - 1, num * n)
15 |
16 | # head recursive version of factorial
17 | def head_factorial(n, num=1):
18 | if n > 0:
19 | return head_factorial(n - 1, num * n)
20 | else:
21 | return num
22 |
23 | # for loop version of factorial
24 | def loop_factorial(n):
25 | num = 1
26 | for i in range(1, n + 1):
27 | num = num * i
28 | return num
29 |
30 |
31 |
32 | print(factorial(5))
33 | print(tail_factorial(5))
34 | print(head_factorial(5))
35 | print(loop_factorial(5))
--------------------------------------------------------------------------------