[Note] Data structure in python
Published:
Các nội dung liên quan về cấu trúc dữ liệu trong python
Singly Linked List (SLL)
# Create a Singly LinkedList with below Properties (1.Head,2.Tail,3.Length)
# methods (1.Push,2.Pop,3.Shift,4.Unshift,5.Get,6.Set,7.Insert,8.Remove,9.Reverse)
import treevizer
class Node:
def __init__(self,val):
self.data = val
self.next = None
class SinglyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def print(self):
treevizer.to_png(self.head, structure_type="ll", dot_path="sll.dot",
png_path="sll.png")
def push(self,nval):
nd = Node(nval)
if self.head is None:
self.head = nd
self.tail = self.head
else:
self.tail.next = nd
self.tail = nd
self.length +=1
def pop(self):
if self.length == 0: return None
if self.length == 1:
self.head = None
self.tail = None
else:
cNode = self.head
for x in range(1, self.length-1):
cNode = cNode.next
self.tail = cNode
cNode.next =None
self.length -=1
return self
def get(self, index):
if self.length > index and index >= 0:
cNode = self.head
if index == 0: return cNode.data
for x in range(1, index+1):
cNode = cNode.next
return cNode.data
return None
def set(self, index,nval):
if self.length > index and index >= 0:
cNode = self.head
if index == 0:
cNode.data = nval
return True
for x in range(1, index+1):
cNode = cNode.next
cNode.data = nval
return True
return False
def reverse(self):
prevNode, curNode = None, self.head
self.tail = curNode
while (curNode):
nextNode = curNode.next
curNode.next = prevNode
prevNode = curNode
curNode = nextNode
self.head = prevNode
def reversePos(self,start,end):
if start > 0 and end <self.length -1:
sNode = eNode = self.head
for x in range(1,start):
sNode = sNode.next
for x in range(1,end+1):
eNode = eNode.next
headNode = sNode
tailNode = eNode.next
prevNode = tailNode
curNode = headNode.next
while(curNode is not tailNode):
nextNode = curNode.next
curNode.next = prevNode
prevNode = curNode
curNode = nextNode
headNode.next = prevNode
def printSll(self):
cNode = self.head
lst = []
while(cNode):
lst.append(cNode.data)
cNode = cNode.next
print(lst)
if __name__ == '__main__':
sll = SinglyLinkedList()
for x in range(1,11): sll.push(x)
sll.print()
sll.printSll()
sll.reversePos(1,7)
sll.printSll()
print('Head [', sll.head.data,']')
print('Tail [',sll.tail.data,']')
Doubly Linked List (DLL)
# Create a Doubly LinkedList with below properties (1.Head,2.Tail,3.Length)
# Problem: DLL FLattening with ChildDLLs or SubChildDLLs
import treevizer
class Node:
def __init__(self,val=None):
self.next = None
self.prev = None
self.data = val
self.child = None
class DoublyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.length = 0
def print(self):
treevizer.to_png(self.head, structure_type="ll", dot_path="dll.dot",
png_path="dll.png")
def addChildDLL(self,index,chlDLL):
if index<0 or index>self.length-1: return None
if index==0:
cNode = self.head
elif index==self.length-1:
cNode = self.tail
else:
cNode = self.head
for x in range(1,index+1): cNode = cNode.next
cNode.child = chlDLL.head
def flattenDLL(self):
psNode = self.head
while(psNode):
if psNode.child is not None:
peNode = psNode.next
csNode = psNode.child
while(csNode): ceNode = csNode; csNode = csNode.next
# ------------------------
psNode.next = psNode.child
psNode.child.prev = psNode
# ------------------------
ceNode.next = peNode
peNode.prev = ceNode
# ------------------------
psNode.child = None
#-------------------------
psNode = psNode.next
def push(self,nval):
nd = Node(nval)
if self.head is None:
self.head = nd
self.tail = self.head
else:
self.tail.next = nd
nd.prev = self.tail
self.tail = nd
self.length +=1
def printDll(self):
# nd=self.head
# while nd: print(nd.stage,end='<->'); nd=nd.next
# print("\n")
print(self.buildMap(self.head))
def buildMap(self,pNode):
tempMap = {}
while(pNode):
if pNode.child is not None:
tempMap[pNode.data] = self.buildMap(pNode.child)
else:
tempMap[pNode.data] = {}
pNode = pNode.next
return tempMap
if __name__ == '__main__':
dll = DoublyLinkedList(); dll1 = DoublyLinkedList(); dll3 = DoublyLinkedList()
dll11 = DoublyLinkedList(); dll33 = DoublyLinkedList()
for x in range(0,10): dll.push(x)
for x in range(10,15): dll1.push(x)
for x in range(30,40): dll3.push(x)
for x in range(120,125): dll11.push(x)
for x in range(330,333): dll33.push(x)
dll1.addChildDLL(2,dll11)
dll3.addChildDLL(3,dll33)
dll.addChildDLL(1,dll1); dll.addChildDLL(3,dll3)
dll.printDll()
dll.flattenDLL() # DLL Flattening Test
dll.printDll()
Stack
Code: using linkedlist (Node)
class Node:
def __init__(self, value):
self.value = value
self.next = None
class Stack:
def __init__(self):
self.top = None
self.size = 0
def is_empty(self):
return self.top is None
def push(self, value):
nd = Node(value)
nd.next = self.top
self.top = nd
self.size+=1
def pop(self):
if self.top is None: return None
value = self.top.value
self.top = self.top.next
self.size -= 1
return value
def peek(self):
if self.top is None: return None
return self.top.value
def length(self): return self.size
def print(self):
cnode = self.top
while cnode:
print(cnode.value,end=" -> ")
cnode=cnode.next
print("None")
if __name__ == '__main__':
stk = Stack()
for i in range(1,11,2): stk.push(i)
stk.print()
stk.push(100)
stk.print()
print(stk.length())
print(stk.peek())
stk.pop()
stk.print()
while stk.length(): val = stk.pop(); print(val)
Code: using List
def __init__(self):
self.arr = []
self.size = 0
def push(self,val):
self.arr.append(val)
self.size = len(self.arr)
def pop(self):
self.arr.pop()
self.size = len(self.arr)
def peek(self):
if self.size >0:
return (self.arr[self.size - 1])
else:
return None
def lookup(self, val):
print(self.arr.index(val)) if val in self.arr else print('Not found')
def printStack(self):
print(self.arr)
if __name__ == "__main__":
stk = stack()
stk.push('Joy')
stk.push('deep')
stk.push('Basu')
stk.lookup('Basu')
print(stk.peek())
stk.pop()
print(stk.peek())
Queue
Code: using linkedlist
class Node:
def __init__(self,val):
self.val = val
self.next = None
class Queue:
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def enqueue(self,val):
nd = Node(val)
if (self.head is None):
self.head = nd
self.tail = self.head
else:
self.tail.next = nd
self.tail = nd
self.size +=1
def dequeue(self):
if self.size == 0: return None
val = self.head.val
if self.head.next:
self.head = self.head.next
else:
self.head = None
self.tail = None
self.size -= 1
return val
def peek(self):
return self.head.val if self.head else None
# ---------------- Optional -----------------------
def printQ(self):
if self.size == 0: return None
cNode = self.head
while(cNode):
print(cNode.val, end=' <- ')
cNode = cNode.next
print('\n')
if __name__ == '__main__':
q = Queue()
q.enqueue('Joy'); q.enqueue('Deep'); q.enqueue('Basu')
print(q.peek())
q.printQ()
print(q.dequeue());print(q.dequeue());print(q.dequeue());print(q.dequeue());print(q.dequ
eue());
q.printQ()
q.enqueue('Joy'); print(q.peek()); print(q.size)
print(q.lookup('Basu'))
Code: using two stacks
class queueFromStack():
def __init__(self):
self.stk1 = [] # stack enqueue or push operation
self.stk2 = [] # stack dequeue or pop operation
self.size = 0
def isEmpty(self):
return self.size==0
def enqueue(self,item):
self.stk1.append(item)
self.size +=1
def dequeue(self):
if self.size==0: return None
if not self.stk2:
while self.stk1: self.stk2.append(self.stk1.pop())
self.size -=1
return self.stk2.pop()
def peek(self):
if self.size == 0: return None
if not self.stk2:
while self.stk1: self.stk2.append(self.stk1.pop())
return self.stk2[-1]
def print(self):
print(" <- ".join(self.stk1))
if __name__ == '__main__':
qs = queueFromStack()
for i in range(3): qs.enqueue(i)
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.isEmpty())
qs.enqueue(3);
qs.enqueue(4);
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
print(qs.dequeue())
print("Stack1: ", qs.stk1, "\nStack2: ", qs.stk2)
##############################################
for i in range(3): qs.enqueue(i)
qs.dequeue()
print(qs.peek())
print(qs.isEmpty())
Code: using dequeue
from collections import deque
class Queue:
def __init__(self):
self.q = deque()
def enqueue(self, item):
self.q.append(item)
def dequeue(self):
return self.q.popleft() if self.q else None
def peek(self):
return self.q[0] if self.q else None
def lookup(self, key):
for item in self.q:
if item == key: return True
return False
def print(self): print("<-".join(map(str,self.q)))
q = Queue()
for x in range(1,10): q.enqueue(x)
q.print()
q.dequeue(); print(q.dequeue())
q.print()
print(q.peek())
print(q.lookup(7))
print(q.peek())
Binary Search Tree (BST)
Code: using node class
# Design a Binary Search Tree (BST) with methods
# 1. Insert, 2. Lookup, 3. Remove, 4. BFS, 5. DFS_InOrder, 6. DFS_PreOrder, 7.
DFS_PostOrder
from tree import drawTree
from collections import deque
class binaryNode:
def __init__(self, val):
self.value = val
self.left = None
self.right = None
########################################################################
class binarySearchTree:
def __init__(self): self.root = None
def print(self): drawTree(self.root)
def insert(self, val):
bNode = binaryNode(val)
if self.root is None: self.root = bNode
curNode = self.root
while curNode:
if bNode.value == curNode.value: return
if bNode.value > curNode.value:
if curNode.right: curNode = curNode.right; continue
curNode.right = bNode; return
else:
if curNode.left: curNode = curNode.left; continue
curNode.left = bNode; return
def search(self, val):
if self.root is None: return None
curNode = self.root
while curNode:
if curNode.value == val: return curNode
if val > curNode.value: curNode = curNode.right; continue
if val < curNode.value: curNode = curNode.left; continue
return None
def remove(self, input_val): ## Not working ##
def helper(node, searchVal):
if node is None: return None
if searchVal < node.value:
node.left = helper(node.left, searchVal)
elif searchVal > node.value:
node.right = helper(node.right, searchVal)
else:
if node.left is None: return node.right
if node.right is None: return node.left
# Node with two children: Get the in-order successor (smallest in the
right subtree)
min_node = node.right
while min_node.left: min_node = min_node.left
node.right = helper(min_node, min_node.value)
return node
self.root = helper(self.root, input_val)
def BFS(self):
q, arr = deque(), []
if self.root is None: return []
q.append(self.root)
while q:
curNode = q.popleft()
arr.append(curNode.value)
if curNode.left: q.append(curNode.left)
if curNode.right: q.append(curNode.right)
return arr
def DFS_InOrder(self):
def traverseInOrder(node, arr): # InOrder: Left Node (recursive) -> Parent Node
-> Right Node (recursive)
if node.left: traverseInOrder(node.left, arr)
arr.append(node.value)
if node.right: traverseInOrder(node.right, arr)
return arr
return traverseInOrder(self.root, []) # recursive call from stage
def DFS_PreOrder(self):
def traversePreOrder(node, arr): # PreOrder: Parent Node -> Left Node (R) ->
Right Node (R)
arr.append(node.value)
if node.left: traversePreOrder(node.left, arr)
if node.right: traversePreOrder(node.right, arr)
return arr
return traversePreOrder(self.root, []) # recursive call from stage
def DFS_PostOrder(self):
def traversePostOrder(node, arr): # PreOrder: Left Node (R) -> Right Node (R) -
> Parent Node
if node.left: traversePostOrder(node.left, arr)
if node.right: traversePostOrder(node.right, arr)
arr.append(node.value)
return arr
return traversePostOrder(self.root, []) # recursive call from stage
####################################################################
if __name__ == '__main__':
myBST = binarySearchTree()
for num in [20, 40, 8, 45, 43, 36, 19, 1, 47, 29, 42, 44, 30]: myBST.insert(num)
# for num in [x for x in range(10)]: myBST.insert(num)
myBST.print()
# exit(0)
print('BFS list:', myBST.BFS())
print('DFS In Order: ', myBST.DFS_InOrder())
print('DFS Pre Order: ', myBST.DFS_PreOrder())
print('DFS Post Order: ', myBST.DFS_PostOrder())
print('Looking up for value (28):', myBST.search(30))
for num in [40, 42, 20]: myBST.remove(num)
myBST.print()
print(myBST.depth())
Heap
Code: Max Heap
from draw_arr2tree import arr2tree
class MaxHeap:
def __init__(self): self.heap = []
def insert(self,value):
self.heap.append(value)
self._heapifyUp(len(self.heap)-1)
def extractMax(self):
if len(self.heap) == 0: return None
if len(self.heap) == 1: return self.heap.pop()
maxVal = self.heap[0]
self.heap[0] = self.heap.pop()
self._heapifyDown(0)
return maxVal
def Max_heapifyArr(self,arr):
self.heap = list(arr)
for index in range((len(arr)//2)-1,-1,-1): # reverse looping on "non-leaf"
nodes --> heapifyDown()
self._heapifyDown(index)
def _swapIndex(self, idx1, idx2): self.heap[idx1], self.heap[idx2] =
self.heap[idx2], self.heap[idx1]
def _heapifyUp(self,index): # Any child (left/right) to its parent comparison
pIndex = (index-1)//2
if index>0 and self.heap[index] > self.heap[pIndex]:
self._swapIndex(index,pIndex)
self._heapifyUp(pIndex)
def _heapifyDown(self,index): # parent to both children (left,right) comparison
largest = index
lcIndex, rcIndex = 2*index+1, 2*index+2
if lcIndex < len(self.heap) and self.heap[lcIndex] > self.heap[largest]:
largest=lcIndex
if rcIndex < len(self.heap) and self.heap[rcIndex] > self.heap[largest]: largest
= rcIndex
if index!=largest:
self._swapIndex(index, largest)
self._heapifyDown(largest)
def print(self):
print(self.heap)
if __name__ == "__main__":
mxhp = MaxHeap()
mxhp.Max_heapifyArr([3, 8, 5, 2, 7, 6, 4, 1]); mxhp.print(); arr2tree(mxhp.heap)
mxhp.insert(0); mxhp.print(); arr2tree(mxhp.heap)
mxhp.insert(100); mxhp.print(); arr2tree(mxhp.heap)
print(mxhp.extractMax()); mxhp.print(); arr2tree(mxhp.heap)
print(mxhp.extractMax()); mxhp.print(); arr2tree(mxhp.heap)
Code: Min heap
class MinHeap:
def __init__(self): self.heap = []
def insert(self,value):
self.heap.append(value)
self._heapifyUp(len(self.heap)-1)
def extractMin(self):
if len(self.heap) == 0: return None
if len(self.heap) == 1: return self.heap.pop()
minVal = self.heap[0]
self.heap[0] = self.heap.pop()
self._heapifyDown(0)
return minVal
def Min_heapifyArr(self,arr):
self.heap = list(arr)
for index in range((len(arr)//2)-1,-1,-1): # reverse looping on "non-leaf"
nodes --> heapifyDown()
self._heapifyDown(index)
def _swapIndex(self, idx1, idx2): self.heap[idx1], self.heap[idx2] =
self.heap[idx2], self.heap[idx1]
def _heapifyUp(self,index): # Any child (left/right) to its parent comparison
pIndex = (index-1)//2
if index>0 and self.heap[index] < self.heap[pIndex]:
self._swapIndex(index,pIndex)
self._heapifyUp(pIndex)
def _heapifyDown(self,index): # parent to both children (left,right) comparison
smallest = index
lcIndex, rcIndex = 2*index+1, 2*index+2
if lcIndex < len(self.heap) and self.heap[lcIndex] < self.heap[smallest]:
smallest=lcIndex
if rcIndex < len(self.heap) and self.heap[rcIndex] < self.heap[smallest]:
smallest = rcIndex
if index!=smallest:
self._swapIndex(index, smallest)
self._heapifyDown(smallest)
def print(self):
print(self.heap)
if __name__ == '__main__':
mnhp = MinHeap()
mnhp.Min_heapifyArr([3,8,5,2,7,6,4,1]); mnhp.print(); arr2tree(mnhp.heap)
mnhp.insert(0); mnhp.print(); arr2tree(mnhp.heap)
mnhp.insert(100); mnhp.print(); arr2tree(mnhp.heap)
print(mnhp.extractMin()); mnhp.print(); arr2tree(mnhp.heap)
print(mnhp.extractMin()); mnhp.print(); arr2tree(mnhp.heap)
Graph
class graph:
def __init__(self): self.graph = {}
def print(self): print(self.graph)
def sort(self): return {k:v for k,v in sorted(self.graph.items())}
def addVertex(self, key):
if key not in self.graph: self.graph[key] = []
def removeVertex(self, key):
if key in self.graph: # removing the node
self.graph.pop(key)
for v in self.graph: # Removing all connections of deleted node
if key in self.graph[v]: self.graph[v].remove(key)
def addEdge(self, fromKey, toKey):
if fromKey == toKey: return
if fromKey in self.graph and toKey in self.graph:
self.graph[fromKey].append(toKey)
self.graph[toKey].append(fromKey)
def deleteEdge(self, fromKey, toKey):
if fromKey == toKey: return None
if fromKey in self.graph and toKey in self.graph:
if toKey in self.graph[fromKey]: self.graph[fromKey].remove(toKey)
if fromKey in self.graph[toKey]: self.graph[toKey].remove(fromKey)
def BFS(self):
q, arr, visited = Queue(), [], []
q.enqueue(min(self.graph.keys()))
node = None
while q.size > 0:
node = q.dequeue()
arr.append(node); visited.append(node)
for key in self.graph[node]:
if key not in visited: q.enqueue(key)
return print('BFS order: ', arr)
def DFS(self):
def traversalDFS(node, arr, visited):
if node not in visited:
arr.append(node); visited.append(node)
for key in self.graph[node]: traversalDFS(key, arr, visited)
return arr
return print('DFS order:',traversalDFS(min(self.graph.keys()),[],[]))
if __name__ == '__main__':
grp = graph()
grp.addVertex(10); grp.addVertex(100); grp.print()
grp.removeVertex(100); grp.removeVertex(89); grp.print()
for item in [0, 1, 2, 3, 4, 5, 6, 7, 8]: grp.addVertex(item)
grp.addEdge(0, 1); grp.addEdge(0, 3); grp.addEdge(3, 2); grp.addEdge(3, 4)
grp.addEdge(3, 5); grp.addEdge(2, 8); grp.addEdge(4, 6); grp.addEdge(6, 7)
grp.print(); grp.deleteEdge(4, 100); grp.removeVertex(4); grp.print()
sgrp = grp.sort(); print(f"Sorted Graph: {sgrp}")
grp.BFS(); grp.DFS()
Trie
class TrieNode:
def __init__(self,val,stop=False):
self.children={}
self.value = val
self.stop = False
class Trie:
def __init__(self):
self.root=TrieNode(val="")
self.length=0 # This tracks the total number of nodes of a Trie
self.keys = 0 # This tracks unique keys/words count of a Trie
def print(self): treevizer.to_png(self.root, structure_type="trie",
dot_path="trie.dot", png_path="trie.png")
def wordsCount (self): return self.keys
########################################################################
def insert(self,word):
node = self.root
for ch in word:
if ch not in node.children: node.children[ch] = TrieNode(ch); self.length+=1
node=node.children[ch]
if not node.stop: node.stop=True; self.keys += 1
####################### Word/Prefix search ########################
def search(self,key,type):
node = self.root
for ch in key:
if ch not in node.children: return False
node=node.children[ch]
# if type='prefix' always True returned, but for word search node.stop value is
returned
return node.stop if type=='word' else True
#################################################################
def delete(self,key):
stack, node = [], self.root
for ch in key:
if ch not in node.children: return False
node=node.children[ch]
stack.append(node)
if node.stop: node.stop = False; self.keys -=1
if node.children: return
# to recursively delete parent node hierarchy if no siblings/other key found in
the hierarchy
stack.insert(0,self.root)
while stack:
node = stack.pop()
pNode = stack[-1]
del pNode.children[node.value]; self.length -=1
# exit loop if siblings (pNode.children) or other key (pNode.stop) is
present
if (pNode is self.root) or pNode.stop or pNode.children: return
################## Autofill Suggestions ##########################
def autofill_suggestions(self,startswith):
node, stack, suggestions = self.root,[],[]
for ch in startswith:
if ch not in node.children: return []
node = node.children[ch]
for ch in node.children: stack.append(("",node.children[ch]))
while stack:
prefix, node = stack.pop()
prefix += node.value
if node.stop: suggestions.append(prefix)
for ch in node.children: stack.append((prefix, node.children[ch]))
return suggestions
###############################################################################
if __name__ == '__main__':
t = Trie()
for wd in
['Cap','Capstone1','Capstone2','Capstone3','Capital','Caps','Caterpillar']: t.insert(wd)
t.print()
print(f"Word (Capstone) search: {t.search('Capstone', 'word')}")
print(f"Word (Capstone1) search: {t.search('Capstone1', 'word')}")
print(f"Prefix/Starts_with (Capta) search: {t.search('Capta', 'prefix')}")
print(f"Prefix/Starts_with (Capita) search: {t.search('Capita', 'prefix')}")
print(f"Distinct Key count: {t.wordsCount()}")
print(f"Total Node count: {t.length}")
print(f"Prompting that starts with: 'Cap' >> {t.autofill_suggestions('Cap')}")
t.delete('Capital'); t.print()
# print(t.search('Cats'))
# print(t.search('Catz'))
# print(t.length)
Matrix
class Matrix:
def __init__(self, rows, cols):
self.rows = rows
self.cols = cols
self.data = [[0 for _ in range(cols)] for _ in range(rows)]
def get(self, row, col):
if 0 <= row < self.rows and 0 <= col < self.cols:
return self.data[row][col]
return None
def set(self, row, col, value):
if 0 <= row < self.rows and 0 <= col < self.cols:
self.data[row][col] = value
else:
print("Index out of bounds")
# Time Complexity: O(rows * cols)
transposed_matrix = Matrix(self.cols, self.rows)
for i in range(self.rows):
for j in range(self.cols):
transposed_matrix.set(j, i, self.data[i][j])
return transposed_matrix
def add(self, other_matrix):
# Time Complexity: O(rows * cols)
if self.rows != other_matrix.rows or self.cols != other_matrix.cols:
print("Matrix dimensions do not match for addition.")
return None
result_matrix = Matrix(self.rows, self.cols)
for i in range(self.rows):
for j in range(self.cols):
result_matrix.set(i, j, self.data[i][j] + other_matrix.get(i, j))
return result_matrix
def multiply(self, other_matrix):
# Time Complexity: O(self.rows * self.cols * other_matrix.cols)
if self.cols != other_matrix.rows:
print("Matrix dimensions are not compatible for multiplication.")
return None
result_matrix = Matrix(self.rows, other_matrix.cols)
for i in range(self.rows):
for j in range(other_matrix.cols):
dot_product = 0
for k in range(self.cols):
dot_product += self.data[i][k] * other_matrix.get(k, j)
result_matrix.set(i, j, dot_product)
return result_matrix
def display(self):
for row in self.data:
print(row)
# Example usage:
matrix1 = Matrix(2, 3)
matrix1.set(0, 0, 1)
matrix1.set(0, 1, 2)
matrix1.set(0, 2, 3)
matrix1.set(1, 0, 4)
matrix1.set(1, 1, 5)
matrix1.set(1, 2, 6)
matrix2 = Matrix(3, 2)
matrix2.set(0, 0, 7)
matrix2.set(0, 1, 8)
matrix2.set(1, 0, 9)
matrix2.set(1, 1, 10)
matrix2.set(2, 0, 11)
matrix2.set(2, 1, 12)
result = matrix1.multiply(matrix2)
result.display()
Sorting Algorithms
Code: Bubble sort
def bubbleSort(self, arr):
for x in range(0, len(arr) - 1): # Outer loop to reduce right boundary of inner
loop by 1
end = len(arr)
for pt in range(1, end): # Inner loop to compare adjacent elements (always
checks from beginning)
if arr[pt - 1] > arr[pt]:
arr[pt - 1], arr[pt] = arr[pt], arr[pt - 1] # Swapping adjacent
elements
end = end - 1
return arr
Code: Selection sort
def selectionSort(self, arr):
for pt1 in range(0, len(arr) - 1): # Outer loop to increase left boundary of inner
loop by 1
smallest = pt1 # pt1 starts with 0, then increases until length of array - 1
for pt2 in range(pt1 + 1, len(arr)): # loop to find the smallest number after
arr[pt1] to replace with arr[pt1]
if arr[pt2] < arr[smallest]: smallest = pt2
if arr[smallest] < arr[pt1]:
arr[pt1], arr[smallest] = arr[smallest], arr[pt1]
return arr
Code: Insertion sort
def insertionSort(self, arr):
for pt1 in range(1, len(arr)):
for pt2 in range(0, pt1):
if arr[pt1] < arr[pt2]:
arr.insert(pt2, arr.pop(pt1))
break
return arr
Code: Merge sort
def mergeSort(self, arr):
def merge(lArr, rArr):
lpt, rpt, result = 0, 0, []
while (lpt < len(lArr) and rpt < len(rArr)):
if lArr[lpt] < rArr[rpt]:
result.append(lArr[lpt]); lpt += 1
else:
result.append(rArr[rpt]); rpt += 1
while (lpt < len(lArr)): result.append(lArr[lpt]); lpt += 1
while (rpt < len(rArr)): result.append(rArr[rpt]); rpt += 1
return result
#-----------------------------------------------------------------------------------
if len(arr) <= 1: return arr
mid = len(arr) // 2
left = self.mergeSort(arr[0:mid])
right = self.mergeSort(arr[mid:])
return merge(left, right)
Code: Quick sort
def quickSort(self, arr):
if len(arr) <= 1: return arr
leftArr, rightArr, pivot = [], [], arr.pop()
for x in arr: leftArr.append(x) if x < pivot else rightArr.append(x)
return self.quickSort(leftArr) + [pivot] + self.quickSort(rightArr)
Code: Radix sort
def radixSort(self, arr):
maxPos = max([len(str(y)) for y in arr])
def getDigit(num, pos): # Helper function to get digit of specified position
return 0 if len(str(num)) < pos else int(str(num)[len(str(num)) - pos])
for pos in range(1, maxPos + 1):
resDict = {x: [] for x in range(10)} # Resetting dictionary to empty list for
keys (0-9)
#####################################
while arr:
num = arr.pop(0)
resDict[getDigit(num, pos)].append(num) # Pop & add array element to dict
(arr positional values = dictionary key)
######################################
for key in resDict: arr = arr + resDict[key] # Re-adding elements to arr as per
dict key order
return arr
Code: Heap sort
def heapsort(self, arr):
n = len(arr)
hp.heapify(arr)
return [hp.heappop(arr) for i in range(n)]
Ref: https://biddu7.github.io
Hết.