├── .idea ├── vcs.xml ├── misc.xml ├── inspectionProfiles │ ├── profiles_settings.xml │ └── Project_Default.xml ├── modules.xml └── IntroductionToAlgorithms.iml ├── InsertionSort.py ├── README.md ├── PowerProblem.py ├── RadixSort.py ├── QuickSort.py ├── OpenAddressingHash.py ├── Stack.py ├── ChainingHash.py ├── HeapSort.py ├── BinarySearch.py ├── RandomizedSelect.py ├── DoubleLinkedList.py ├── LongestCommonSubsequence.py ├── MergeSort.py ├── Queue_.py ├── MiddleSelect.py ├── FibonacciNumber.py ├── Graph_BFS&DFS.py ├── Dijkstra.py ├── JumpList.py ├── BinarySearchTree.py ├── StrasssenAlgorithm.py └── RedBlackTree.py /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 12 | -------------------------------------------------------------------------------- /InsertionSort.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def InsertionSort(A, n): 5 | for j in range(1, n): 6 | key = A[j] 7 | # Insert A[j] into the sorted sequence[1...j-1] 8 | i = j - 1 9 | while i >= 0 and A[i] > key: 10 | A[i + 1] = A[i] 11 | i = i-1 12 | A[i+1] = key 13 | return A 14 | 15 | A = [] 16 | s = random.randint(5, 100) 17 | for i in range(0, s): 18 | A.append(random.randint(0, 1000)) 19 | print A 20 | print InsertionSort(A, len(A)) 21 | -------------------------------------------------------------------------------- /.idea/IntroductionToAlgorithms.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 简介 2 | 这是我阅读《算法导论》时候实现的部分算法。 3 | # 已实现算法 4 | 5 | 1. 插入排序 6 | 2. 归并排序 7 | 3. 二分查找 8 | 4. 快速阶乘 9 | 5. 斐波那契数列(包括原始算法、线性算法、递归矩阵算法) 10 | 6. Strassen算法 11 | 7. 堆排序 12 | 8. 基数排序 13 | 9. 中分查找 14 | 10. 链表哈希算法 15 | 11. 开放地址哈希算法 16 | 12. 随机化查找 17 | 13. 随机化快速排序 18 | 14. 二分查找树 19 | 15. 红黑树 20 | 16. 栈 21 | 17. 双向链表 22 | 18. 循环队列 23 | 19. 最长子字符串问题 24 | 20. 图的广度/深度优先搜索 25 | 21. 单源最短路径Dijkstra算法 26 | 22. 跳跃表 27 | 28 | # 相关资源 29 | 30 | [《算法导论》快速指南:我是如何10天入门算法导论的。](https://zhuanlan.zhihu.com/p/24798324) 31 | -------------------------------------------------------------------------------- /PowerProblem.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def MyPow(x, n): 5 | if n == 0: 6 | return 1 7 | if n == 1: 8 | return x 9 | if n == 2: 10 | return x * x 11 | if n % 2 == 0: 12 | return MyPow(MyPow(x, n / 2), 2) 13 | if n % 2 == 1: 14 | return MyPow(MyPow(x, n / 2), 2) * x 15 | 16 | 17 | print "Now Displaying PowerProblem." 18 | x = random.randint(4, 999) 19 | n = random.randint(3, 40) 20 | print x, " powers ", n 21 | # x = 1 22 | # n = 2 23 | print MyPow(x, n), " comparing to build_in function: ", pow(x, n) 24 | -------------------------------------------------------------------------------- /RadixSort.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def GetI(n): 5 | i = 0 6 | while n != 0: 7 | n /= 10 8 | i += 1 9 | return i 10 | 11 | 12 | def GetKey(n, i): 13 | ret = n 14 | ret /= pow(10, i) 15 | return ret % 10 16 | 17 | 18 | def RadixSort(A): 19 | for i in range(0, GetI(A[0])): 20 | A.sort(lambda x, y: cmp(GetKey(x, i), GetKey(y, i))) 21 | return A 22 | 23 | 24 | print "Now displaying Radix Sort." 25 | A = [] 26 | s = random.randint(4, 100) 27 | for i in range(0, s): 28 | A.append(random.randint(0, 999)) 29 | print A 30 | print RadixSort(A) 31 | print "DEBUG" 32 | -------------------------------------------------------------------------------- /QuickSort.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def Partition(A, p, r): 5 | it = random.randint(p, r) # To get a randomized elem. 6 | A[p], A[it] = A[it], A[p] 7 | x = A[p] 8 | i = p - 1 9 | for j in range(p, r + 1): 10 | if A[j] <= x: 11 | i += 1 12 | A[i], A[j] = A[j], A[i] 13 | A[p], A[i] = A[i], A[p] 14 | return i 15 | 16 | 17 | def QuickSort(A, p, r): 18 | if r > p: 19 | q = Partition(A, p, r) 20 | QuickSort(A, p, q - 1) 21 | QuickSort(A, q + 1, r) 22 | return A 23 | 24 | 25 | print "Now displaying QuickSort" 26 | A = [] 27 | s = random.randint(5, 100) 28 | for i in range(0, s): 29 | A.append(random.randint(0, 1000)) 30 | print A 31 | print QuickSort(A, 0, len(A) - 1) 32 | -------------------------------------------------------------------------------- /OpenAddressingHash.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def HashInsert(e, T, s): 5 | for i in range(0, s): 6 | if T[(e + i) % s] == -1: 7 | T[(e + i) % s] = e 8 | return True 9 | return False 10 | 11 | 12 | def HashSearch(e, T, s): 13 | for i in range(0, s): 14 | if T[(e + i) % s] == e: 15 | return (e + i) % s 16 | return False 17 | 18 | 19 | print "Now displaying Open Addressing Hash." 20 | s = 13 21 | A = [] 22 | T = [-1 for i in range(0, s)] 23 | t = random.randint(5, 100) 24 | for i in range(0, t): 25 | A.append(random.randint(0, 1000)) 26 | for e in A: 27 | HashInsert(e, T, s) 28 | print T 29 | e = random.choice(A) 30 | i = HashSearch(e, T, s) 31 | print "The selected elem ", e, " is in Slot:", i 32 | -------------------------------------------------------------------------------- /Stack.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Stack: 5 | def __init__(self): 6 | self.top = -1 7 | self.s = 100 8 | self.S = [0 for i in range(0, self.s)] 9 | 10 | def StackEmpty(self): 11 | if self.top == -1: 12 | return True 13 | return False 14 | 15 | def Push(self, x): 16 | if self.top == self.s - 1: 17 | return False 18 | self.top += 1 19 | self.S[self.top] = x 20 | return True 21 | 22 | def Pop(self): 23 | if self.StackEmpty(): 24 | return False 25 | else: 26 | self.top -= 1 27 | return self.S[self.top + 1] 28 | 29 | 30 | S = Stack() 31 | for i in range(0, 120): 32 | S.Push(random.randint(0,999)) 33 | 34 | while not S.StackEmpty(): 35 | print S.Pop() 36 | -------------------------------------------------------------------------------- /ChainingHash.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def HashDelete(e, T, s): 5 | i1, i2 = HashSearch(e, T, s) 6 | T[i1].pop(i2) 7 | 8 | 9 | def HashSearch(e, T, s): 10 | for i in range(0, len(T[e % s])): 11 | if T[e % s][i] == e: 12 | return e % s, i 13 | return None 14 | 15 | 16 | def HashInsert(e, T, s): 17 | T[e % s].append(e) 18 | 19 | 20 | print "Now displaying Chaining Hash" 21 | s = 13 22 | A = [] 23 | T = [[] for i in range(0, s)] 24 | t = random.randint(5, 100) 25 | for i in range(0, t): 26 | A.append(random.randint(0, 1000)) 27 | for e in A: 28 | HashInsert(e, T, s) 29 | print T 30 | e = random.choice(A) 31 | 32 | i1, i2 = HashSearch(e, T, s) 33 | print "The selected elem ", e, " is in Slot:", i1, " Position: ", i2 34 | HashDelete(e, T, s) 35 | print "After Deletion:" 36 | print T -------------------------------------------------------------------------------- /HeapSort.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def MaxHeapify(A, i, s): 5 | l = i * 2 6 | r = i * 2 + 1 7 | largest = i 8 | if l < s and A[l] > A[i]: 9 | largest = l 10 | if r < s and A[r] > A[largest]: 11 | largest = r 12 | if largest != i: 13 | A[i], A[largest] = A[largest], A[i] 14 | MaxHeapify(A, largest, s) 15 | 16 | 17 | def BuildMaxHeap(A, s): 18 | for i in range(0, len(A) / 2)[::-1]: 19 | MaxHeapify(A, i, s) 20 | return A 21 | 22 | 23 | def HeapSort(A): 24 | s = len(A) 25 | BuildMaxHeap(A, s) 26 | 27 | for i in range(1, len(A))[::-1]: 28 | A[0], A[i] = A[i], A[0] 29 | s -= 1 30 | MaxHeapify(A, 0, s) 31 | return A 32 | 33 | 34 | print "Now displaying HeapSort" 35 | A = [] 36 | s = random.randint(5, 100) 37 | for i in range(0, s): 38 | A.append(random.randint(0, 1000)) 39 | print A 40 | print HeapSort(A) 41 | -------------------------------------------------------------------------------- /BinarySearch.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def InsertionSort(A, n): 5 | for j in range(1, n): 6 | key = A[j] 7 | # Insert A[j] into the sorted sequence[1...j-1] 8 | i = j - 1 9 | while i >= 0 and A[i] > key: 10 | A[i + 1] = A[i] 11 | i = i - 1 12 | A[i + 1] = key 13 | return A 14 | 15 | 16 | def BinarySearch(A, p, r, key): 17 | if p >= r: 18 | return -1 19 | q = (p + r) / 2 20 | if A[q] == key: 21 | return q 22 | elif A[q] < key: 23 | return BinarySearch(A, q + 1, r, key) 24 | else: 25 | return BinarySearch(A, p, q, key) 26 | 27 | 28 | # Pre procedure. 29 | A = [] 30 | s = random.randint(5, 100) 31 | for i in range(0, s): 32 | A.append(random.randint(0, 1000)) 33 | A = InsertionSort(A, len(A)) 34 | key = random.choice(A) 35 | 36 | print "Now displaying BinarySearch." 37 | print A 38 | print key 39 | print BinarySearch(A, 0, len(A) - 1, key) 40 | -------------------------------------------------------------------------------- /RandomizedSelect.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def RandomizedPartition(A, p, r): 5 | it = random.randint(p, r) 6 | A[p], A[it] = A[it], A[p] 7 | x = A[p] # To get a randomized elem. 8 | i = p - 1 9 | for j in range(p, r + 1): 10 | if A[j] <= x: 11 | i += 1 12 | A[i], A[j] = A[j], A[i] 13 | A[p], A[i] = A[i], A[p] 14 | return i 15 | 16 | 17 | def RandomizedSelect(A, p, r, i): 18 | # if p == r: 19 | # return A[p] 20 | q = RandomizedPartition(A, p, r) 21 | if q == i: 22 | return A[q] 23 | if q > i: 24 | return RandomizedSelect(A, p, q - 1, i) 25 | if q < i: 26 | return RandomizedSelect(A, q + 1, r, i) 27 | 28 | 29 | print "Now displaying Randomized Select" 30 | A = [] 31 | s = random.randint(5, 100000) 32 | for i in range(0, s): 33 | A.append(random.randint(0, 100000000)) 34 | # print A 35 | i = random.randint(0, s - 1) 36 | print "The position of ", i, "is :", RandomizedSelect(A, 0, len(A) - 1, i) 37 | A.sort() 38 | print A[i] 39 | -------------------------------------------------------------------------------- /DoubleLinkedList.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, key, prev=None, next_=None): 3 | self.key = key 4 | self.prev = prev 5 | self.next_ = next_ 6 | 7 | 8 | class List: 9 | def __init__(self): 10 | self.nil = Node("NIL") 11 | self.nil.next_ = self.nil 12 | self.nil.prev = self.nil 13 | # Two guards link together. 14 | 15 | def ListInsert(self, x): 16 | x.next_ = self.nil.next_ 17 | self.nil.next_.prev = x 18 | self.nil.next_ = x 19 | x.prev = self.nil 20 | 21 | def ListSearch(self, k): 22 | x = self.nil.next_ 23 | while x.key != k and x != self.nil: 24 | x = x.next_ 25 | return x 26 | 27 | def ListDelete(self, x): 28 | x.prev.next_ = x.next_ 29 | x.next_.prev = x.prev 30 | 31 | 32 | L = List() 33 | for i in range(0, 5): 34 | L.ListInsert(Node(i)) 35 | A = [] 36 | for i in range(0, 5): 37 | A.append(L.ListSearch(i)) 38 | print A[i].key 39 | for i in A: 40 | L.ListDelete(i) 41 | print "DEBUG" 42 | -------------------------------------------------------------------------------- /LongestCommonSubsequence.py: -------------------------------------------------------------------------------- 1 | def LCSString(b, X, i, j): 2 | if i == -1 or j == -1: 3 | return 4 | if b[i][j] == "SLOPE": 5 | a = LCSString(b, X, i - 1, j - 1) 6 | return X[i] if a is None else a + X[i] 7 | elif b[i][j] == "UP": 8 | return LCSString(b, X, i - 1, j) 9 | else: 10 | return LCSString(b, X, i, j - 1) 11 | 12 | def LCS(X, Y): 13 | b = [[0 for i in range(0, len(Y))] for i in range(0, len(X))] 14 | c = [[0 for i in range(0, len(Y) + 1)] for i in range(0, len(X) + 1)] 15 | for i in range(0, len(X)): 16 | for j in range(0, len(Y)): 17 | if X[i] == Y[j]: 18 | c[i + 1][j + 1] = c[i][j] + 1 19 | b[i][j] = "SLOPE" 20 | elif c[i][j + 1] > c[i + 1][j]: 21 | c[i + 1][j + 1] = c[i][j + 1] 22 | b[i][j] = "UP" 23 | else: 24 | c[i + 1][j + 1] = c[i + 1][j] 25 | b[i][j] = "LEFT" 26 | return LCSString(b, X, len(X) - 1, len(Y) - 1) 27 | 28 | print LCS("ABCBDAB", "BDCABA") 29 | -------------------------------------------------------------------------------- /MergeSort.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def MergeSort(A, p, r): 5 | q = (p + r) / 2 # Find the middle 6 | if p < r: 7 | MergeSort(A, p, q) # MergeSort A[p...q] 8 | MergeSort(A, q + 1, r) # MergeSort A[p+1....r] 9 | return Merge(A, p, q, r) 10 | 11 | 12 | # The guard in Merge() 13 | MAX = 10000 14 | 15 | 16 | def Merge(A, p, q, r): 17 | L = [] 18 | R = [] 19 | for i in range(p, q + 1): # Copy the left side. 20 | L.append(A[i]) 21 | for i in range(q + 1, r + 1): # Copy the right side. 22 | R.append(A[i]) 23 | L.append(MAX) # Add guard to the end. 24 | R.append(MAX) # Add guard to the end. 25 | i = 0 26 | j = 0 27 | for k in range(p, r + 1): 28 | if L[i] < R[j]: 29 | A[k] = L[i] 30 | i = i + 1 31 | else: 32 | A[k] = R[j] 33 | j = j + 1 34 | return A 35 | 36 | 37 | print "Now displaying MergeSort" 38 | A = [] 39 | s = random.randint(5, 100) 40 | for i in range(0, s): 41 | A.append(random.randint(0, 1000)) 42 | print A 43 | print MergeSort(A, 0, len(A) - 1) 44 | -------------------------------------------------------------------------------- /Queue_.py: -------------------------------------------------------------------------------- 1 | class Queue_(): 2 | def __init__(self, length=10): 3 | self.head = 0 4 | self.tail = 1 5 | self.length = length 6 | self.Q = [0 for i in range(self.length)] 7 | # Actually there are only length-1 spaces in Q. 8 | # And we need to leave one space to determine whether fullStack or emptyStack. 9 | # So the available space is length - 2 10 | 11 | def QueueEmpty(self): 12 | if (self.head + 1) % self.length == self.tail: 13 | return True 14 | return False 15 | 16 | def QueueFull(self): 17 | if (self.tail + 1) % self.length == self.head: 18 | return True 19 | return False 20 | 21 | def Enqueue(self, x): 22 | if self.QueueFull(): 23 | return False 24 | else: 25 | self.Q[self.tail] = x 26 | self.tail = (self.tail + 1) % self.length 27 | return True 28 | 29 | def Dequeue(self): 30 | if self.QueueEmpty(): 31 | return None 32 | else: 33 | self.head += 1 34 | return self.Q[self.head] 35 | 36 | 37 | Q = Queue_() 38 | for i in range(0, 10): 39 | Q.Enqueue(i) 40 | 41 | while not Q.QueueEmpty(): 42 | print Q.Dequeue() 43 | -------------------------------------------------------------------------------- /MiddleSelect.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def Partition(A, p, r): 5 | x = A[p] # To get a randomized elem. 6 | i = p - 1 7 | for j in range(p, r + 1): 8 | if A[j] <= x: 9 | i += 1 10 | A[i], A[j] = A[j], A[i] 11 | A[p], A[i] = A[i], A[p] 12 | return i 13 | 14 | 15 | def QuickSort(A, p, r): 16 | if r > p: 17 | q = Partition(A, p, r) 18 | QuickSort(A, p, q - 1) 19 | QuickSort(A, q + 1, r) 20 | return A 21 | 22 | 23 | def MiddlePartition(A, p, r): 24 | # To get the middle of the elem. 25 | T = [[A[i] for i in range(j * 5, j * 5 + 5)] for j in range(0, (0 + len(A)) / 5)] 26 | m = [] 27 | for i in T: 28 | QuickSort(i, 0, 4) 29 | m.append(i[2]) 30 | QuickSort(m, 0, len(m) - 1) 31 | mm = m[len(m) / 2] 32 | 33 | x = mm 34 | i = p - 1 35 | for j in range(p, r + 1): 36 | if A[j] <= x: 37 | i += 1 38 | A[i], A[j] = A[j], A[i] 39 | A[p], A[i] = A[i], A[p] 40 | return i 41 | 42 | 43 | def MiddleSelect(A, p, r, i): 44 | if p == r: 45 | return A[p] 46 | q = MiddlePartition(A, p, r) 47 | if q == i: 48 | return A[q] 49 | if q > i: 50 | return MiddleSelect(A, p, q - 1, i) 51 | if q < i: 52 | return MiddleSelect(A, q + 1, r, i) 53 | 54 | 55 | print "Now displaying Middle Select" 56 | A = [] 57 | s = random.randint(5, 100) 58 | for i in range(0, s): 59 | A.append(random.randint(0, 1000)) 60 | print A 61 | i = random.randint(0, s) 62 | print "The position of ", i, "is :", MiddleSelect(A, 0, len(A) - 1, i) 63 | 64 | -------------------------------------------------------------------------------- /FibonacciNumber.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def NaiveFibonacci(a): 5 | if a == 0: 6 | return 0 7 | if a == 1: 8 | return 1 9 | else: 10 | return NaiveFibonacci(a - 1) + NaiveFibonacci(a - 2) 11 | 12 | 13 | def LinearFibonacci(a): 14 | A = [0, 1] 15 | for i in range(2, a + 1): 16 | A.append(A[i - 1] + A[i - 2]) 17 | return A[a] 18 | 19 | 20 | def MatrixMultiply(m1, m2): 21 | result = [[0 for i in range(len(m2[0]))] for i in range(len(m1))] 22 | for i in range(0, len(m1)): # The number of the row is defined by m1 23 | for j in range(0, len(m2[0])): # The number of column is defined by m2 24 | for k in range(len(m1[0])): 25 | result[i][j] += m1[i][k] * m2[k][j] 26 | return result 27 | 28 | 29 | def RecursiveSquaring(n): 30 | basicMatrix = [[1, 1], [1, 0]] 31 | if n == 0: 32 | return basicMatrix # Identity matrix 33 | if n == 1: 34 | return basicMatrix 35 | else: 36 | matrix = RecursiveSquaring(n / 2) 37 | if n % 2 == 0: 38 | return MatrixMultiply(matrix, matrix) 39 | if n % 2 == 1: 40 | return MatrixMultiply(MatrixMultiply(matrix, matrix), basicMatrix) 41 | 42 | 43 | def AdvanceFibonacci(n): 44 | matrix = RecursiveSquaring(n) 45 | return matrix[0][1] 46 | 47 | 48 | a = random.randint(0, 100) 49 | print "Now Displaying Fibonacci Number(Naive Method)" 50 | print "the Fibonacci number of ", a, " is ", NaiveFibonacci(a) 51 | print "Now Displaying Fibonacci Number(Linear)" 52 | print "the Fibonacci number of ", a, " is ", LinearFibonacci(a) 53 | print "Now Displaying Fibonacci Number(logn)" 54 | print "the Fibonacci number of ", a, " is ", AdvanceFibonacci(a) 55 | -------------------------------------------------------------------------------- /Graph_BFS&DFS.py: -------------------------------------------------------------------------------- 1 | class Vertex: 2 | def __init__(self, key, adjacent): 3 | self.key = key 4 | self.adjacent = adjacent 5 | 6 | 7 | class Graph: 8 | def __init__(self): 9 | self.node = {} 10 | 11 | def AddVertex(self, key, adjance=[], rank=[]): 12 | A = [] 13 | if rank == []: 14 | rank = [1 for i in range(0, len(adjance))] 15 | for i in range(0, len(adjance)): 16 | A.append((self.node[adjance[i]], rank[i])) 17 | 18 | self.node[key] = Vertex(key, A) 19 | 20 | def AddEdge(self, u, v, r): 21 | for i in self.node[u].adjacent: 22 | if i[0].key == v: 23 | return False 24 | self.node[u].adjacent.append((self.node[v], r)) 25 | 26 | def BDFS(self, s, t): 27 | OPEN = [] 28 | CLOSE = [] 29 | OPEN.append(self.node[s]) 30 | self.Recursion(OPEN, CLOSE, t) 31 | return CLOSE 32 | 33 | def Recursion(self, OPEN, CLOSE, s): 34 | if len(OPEN) == 0: 35 | return 36 | i = OPEN.pop(0) 37 | CLOSE.append(i) 38 | for j in i.adjacent: 39 | isUndiscover = True 40 | for k in OPEN: 41 | if j[0] == k: 42 | isUndiscover = False 43 | for k in CLOSE: 44 | if j[0] == k: 45 | isUndiscover = False 46 | if (isUndiscover): 47 | if s == "BFS": 48 | OPEN.append(j[0]) 49 | elif s == "DFS": 50 | OPEN.insert(0, j[0]) 51 | self.Recursion(OPEN, CLOSE,s) 52 | 53 | 54 | G = Graph() 55 | G.AddVertex("H") 56 | G.AddVertex("I") 57 | G.AddVertex("J") 58 | G.AddVertex("K") 59 | G.AddVertex("L") 60 | G.AddVertex("M") 61 | G.AddVertex("N") 62 | G.AddVertex("O") 63 | G.AddVertex("D", ["H", "I"]) 64 | G.AddVertex("E", ["J", "K"]) 65 | G.AddVertex("F", ["L", "M"]) 66 | G.AddVertex("G", ["N", "O"]) 67 | G.AddVertex("B", ["D", "E"]) 68 | G.AddVertex("C", ["F", "G"]) 69 | G.AddVertex("A", ["B", "C"]) 70 | LIST = G.BDFS("A", "BFS") 71 | print [i.key for i in LIST] 72 | LIST = G.BDFS("A", "DFS") 73 | print [i.key for i in LIST] 74 | -------------------------------------------------------------------------------- /Dijkstra.py: -------------------------------------------------------------------------------- 1 | class Vertex: 2 | def __init__(self, key, adjacent): 3 | self.key = key 4 | self.adjacent = adjacent 5 | self.prev = None 6 | 7 | 8 | class Graph: 9 | def __init__(self): 10 | self.node = {} 11 | 12 | def AddVertex(self, key, adjance=[], rank=[]): 13 | A = [] 14 | if rank == []: 15 | rank = [1 for i in range(0, len(adjance))] 16 | for i in range(0, len(adjance)): 17 | A.append((self.node[adjance[i]], rank[i])) 18 | 19 | self.node[key] = Vertex(key, A) 20 | 21 | def AddEdge(self, u, v, r): 22 | for i in self.node[u].adjacent: 23 | if i[0].key == v: 24 | return False 25 | self.node[u].adjacent.append((self.node[v], r)) 26 | 27 | def Dijkstra(self, s, e): 28 | OPEN = [] 29 | CLOSE = [] 30 | OPEN.append((self.node[s], 0)) 31 | self.Recursion(OPEN, CLOSE, e) 32 | RET = [] 33 | i = self.node[e] 34 | while i != None: 35 | RET.append(i) 36 | i = i.prev 37 | RET.reverse() 38 | return RET 39 | 40 | def Contains(self, list, e): 41 | for i in list: 42 | if i[0] == e: 43 | return i 44 | return False 45 | 46 | def Recursion(self, OPEN, CLOSE, e): 47 | if self.Contains(CLOSE, e): 48 | return 49 | if len(OPEN) == 0: 50 | return 51 | i = OPEN.pop(0) 52 | CLOSE.append(i) 53 | for j in i[0].adjacent: 54 | if self.Contains(CLOSE, j[0]): 55 | continue 56 | con = self.Contains(OPEN, j[0]) 57 | if con: 58 | if con[1] > i[1] + j[1]: 59 | OPEN.remove(con) 60 | else: 61 | continue 62 | j[0].prev = i[0] 63 | rank = i[1] + j[1] 64 | OPEN.append((j[0], rank)) 65 | OPEN.sort(lambda x, y: cmp(x[1], y[1])) 66 | self.Recursion(OPEN, CLOSE, e) 67 | 68 | 69 | G = Graph() 70 | G.AddVertex("s") 71 | G.AddVertex("t") 72 | G.AddVertex("x") 73 | G.AddVertex("y") 74 | G.AddVertex("z") 75 | G.AddEdge("s", "t", 10) 76 | G.AddEdge("s", "y", 5) 77 | G.AddEdge("t", "x", 1) 78 | G.AddEdge("t", "y", 2) 79 | G.AddEdge("x", "z", 4) 80 | G.AddEdge("y", "t", 3) 81 | G.AddEdge("y", "x", 9) 82 | G.AddEdge("y", "z", 2) 83 | G.AddEdge("z", "s", 7) 84 | G.AddEdge("z", "x", 6) 85 | path = G.Dijkstra("s", "x") 86 | print [i.key for i in path] 87 | print "DEBUG" 88 | -------------------------------------------------------------------------------- /JumpList.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Node: 5 | def __init__(self, key, next_=None, prev=None, down=None): 6 | self.key = key 7 | self.next_ = next_ 8 | self.prev = prev 9 | self.down = down 10 | 11 | 12 | class List: 13 | def __init__(self): 14 | minNum, maxNum = -1, 10000 15 | self.L = Node(minNum) 16 | E = Node(maxNum) 17 | self.L.next_, E.prev = E, self.L 18 | 19 | 20 | class JList: 21 | def __init__(self): 22 | self.JL = [] 23 | self.JL.append(List()) 24 | 25 | def AddLevel(self): 26 | self.JL.append(List()) 27 | self.JL[len(self.JL) - 1].L.down = self.JL[len(self.JL) - 2].L 28 | 29 | def Add(self, key): 30 | e = Node(key) 31 | i = 0 32 | while random.randint(0, 9) % 2 == 0: 33 | i += 1 34 | while len(self.JL) < i + 1: 35 | self.AddLevel() 36 | it = self.JL[i].L 37 | while it.key < e.key: 38 | it = it.next_ 39 | e.next_ = it 40 | e.prev = it.prev 41 | it.prev.next_ = e 42 | it.prev = e 43 | self.RecursiveAdd(e.prev.down, e, key) 44 | return True 45 | 46 | def RecursiveAdd(self, itt, e, key): 47 | if itt == None: 48 | return 49 | e.down = en = Node(key) 50 | while itt.key < en.key: 51 | itt = itt.next_ 52 | en.next_ = itt 53 | en.prev = itt.prev 54 | itt.prev.next_ = en 55 | itt.prev = en 56 | itt = en.prev.down 57 | self.RecursiveAdd(itt, en, key) 58 | 59 | def Search(self, key, Level=None): 60 | i = self.JL[len(self.JL) - 1].L if Level is None else Level 61 | while i.key < key: 62 | i = i.next_ 63 | if i.prev.down != None: 64 | return self.Search(key, i.prev.down) 65 | elif i.key == key: 66 | return i 67 | else: 68 | return False 69 | 70 | def Delete(self, key, Level=None): 71 | i = self.JL[len(self.JL) - 1].L if Level is None else Level 72 | while i.key < key: 73 | i = i.next_ 74 | if i.key == key: 75 | i.prev.next_ = i.next_ 76 | i.next_.prev = i.prev 77 | while i.down is not None: 78 | i = i.down 79 | i.prev.next_ = i.next_ 80 | i.next_.prev = i.prev 81 | elif i.prev.down != None: 82 | return self.Delete(key, i.prev.down) 83 | else: 84 | return False 85 | 86 | test = JList() 87 | for i in range(0, 10): 88 | test.Add(i) 89 | n = test.Search(6) 90 | for i in range(0, 1024): 91 | test.Delete(i) 92 | -------------------------------------------------------------------------------- /BinarySearchTree.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Tree: 5 | def __init__(self): 6 | self.l = None 7 | self.r = None 8 | self.k = None 9 | self.p = None 10 | 11 | def Transplant(self, u, v): 12 | if u.p is None: 13 | u.k = v.k 14 | 15 | elif u is u.p.l: 16 | u.p.l = v 17 | else: 18 | u.p.r = v 19 | if v.k is not None: 20 | v.p = u.p 21 | 22 | def TreeDelete(self, z): 23 | 24 | if z.l.k is None: 25 | self.Transplant(z, z.r) 26 | elif z.r.k is None: 27 | self.Transplant(z, z.l) 28 | else: 29 | y = z.r.TreeMinimum() 30 | if y.p is not z: 31 | self.Transplant(y, y.r) 32 | y.r = z.r 33 | y.r.p = y 34 | self.Transplant(z, y) 35 | y.l = z.l 36 | y.l.p = y 37 | 38 | def Insert(self, T, i, P): 39 | if T.k == None: 40 | T.k = i 41 | T.p = P 42 | T.l = Tree() 43 | T.r = Tree() 44 | elif T.k > i: 45 | self.Insert(T.l, i, T) 46 | elif T.k < i: 47 | self.Insert(T.r, i, T) 48 | 49 | def Sort(self, A): 50 | # random.shuffle(A) # This is use to get randomized Tree. 51 | for i in range(0, len(A)): 52 | self.Insert(self, A[i], None) 53 | 54 | def InOrderTreeWalk(self, A): 55 | if self.k is not None: 56 | self.l.InOrderTreeWalk(A) 57 | A.append(self) 58 | self.r.InOrderTreeWalk(A) 59 | 60 | def TreeSearch(self, k): 61 | if self.k == k or self.k is None: 62 | return self 63 | elif k < self.k: 64 | return self.l.TreeSearch(k) 65 | else: 66 | return self.r.TreeSearch(k) 67 | 68 | def IterativeTreeSearch(self, k): 69 | while self.k is not None and self.k != k: 70 | if k < self.k: 71 | self = self.l 72 | else: 73 | self = self.r 74 | return self 75 | 76 | def TreeMinimum(self): 77 | while self.l.k is not None: 78 | self = self.l 79 | return self 80 | 81 | def TreeMaxinum(self): 82 | while self.r.k is not None: 83 | self = self.r 84 | return self 85 | 86 | 87 | A = [] 88 | s = random.randint(5, 100) 89 | for i in range(0, s): 90 | A.append(random.randint(0, 1000)) 91 | k = random.choice(A) 92 | t = Tree() 93 | t.Sort(A) 94 | A = [] 95 | t.InOrderTreeWalk(A) 96 | print "Using InOrderWalk:", [A[i].k for i in range(0, len(A))] 97 | print "Using Recursion method to find ", k, " :", t.TreeSearch(k).k 98 | print "Using Interval method to find ", k, " :", t.IterativeTreeSearch(k).k 99 | print "Finding the Minimum elem :", t.TreeMinimum().k 100 | print "Finding the Maximum elem :", t.TreeMaxinum().k 101 | d = random.choice([A[i].k for i in range(len(A))]) 102 | print "we are going to delete:",d 103 | t.TreeDelete(t.TreeSearch(d)) 104 | B = [] 105 | t.InOrderTreeWalk(B) 106 | print "After deletion:",[B[i].k for i in range(0, len(B))] 107 | -------------------------------------------------------------------------------- /StrasssenAlgorithm.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | def MatrixPlus(m1, m2): 5 | return [[m1[i][j] + m2[i][j] for j in range(len(m1))] for i in range(len(m2))] 6 | 7 | 8 | def MatrixMultiply(m1, m2): 9 | result = [[0 for i in range(len(m2[0]))] for i in range(len(m1))] 10 | for i in range(0, len(m1)): # The number of the row is defined by m1 11 | for j in range(0, len(m2[0])): # The number of column is defined by m2 12 | for k in range(len(m1[0])): 13 | result[i][j] += m1[i][k] * m2[k][j] 14 | return result 15 | 16 | 17 | def Merge(C00, C01, C10, C11): 18 | l = len(C00) * 2 19 | ret = [[0 for i in range(l)] for i in range(l)] 20 | for i in range(l / 2): 21 | for j in range(l / 2): 22 | ret[i][j] = C00[i][j] 23 | ret[i][j + l / 2] = C01[i][j] 24 | ret[i + l / 2][j] = C10[i][j] 25 | ret[i + l / 2][j + l / 2] = C11[i][j] 26 | return ret 27 | 28 | 29 | def MatrixMinus(m1, m2): 30 | return [[m1[i][j] - m2[i][j] for j in range(len(m1))] for i in range(len(m2))] 31 | 32 | 33 | def Split(M): 34 | q = len(M) / 2 35 | MM00 = [[M[i][j] for j in range(0, q)] for i in range(0, q)] 36 | MM01 = [[M[i][j] for j in range(q, len(M))] for i in range(0, q)] 37 | MM10 = [[M[i][j] for j in range(0, q)] for i in range(q, len(M))] 38 | MM11 = [[M[i][j] for j in range(q, len(M))] for i in range(q, len(M))] 39 | return MM00, MM01, MM10, MM11 40 | 41 | 42 | def StrassenAlgorithm(A, B): 43 | if len(A) == 2: 44 | M1 = (A[0][0] + A[1][1]) * (B[0][0] + B[1][1]) 45 | M2 = (A[1][0] + A[1][1]) * B[0][0] 46 | M3 = A[0][0] * (B[0][1] - B[1][1]) 47 | M4 = A[1][1] * (B[1][0] - B[0][0]) 48 | M5 = (A[0][0] + A[0][1]) * B[1][1] 49 | M6 = (A[1][0] - A[0][0]) * (B[0][0] + B[0][1]) 50 | M7 = (A[0][1] - A[1][1]) * (B[1][0] + B[1][1]) 51 | C00 = M1 + M4 - M5 + M7 52 | C01 = M3 + M5 53 | C10 = M2 + M4 54 | C11 = M1 - M2 + M3 + M6 55 | return [[C00, C01], [C10, C11]] 56 | else: 57 | pass 58 | AA00, AA01, AA10, AA11 = Split(A) 59 | BB00, BB01, BB10, BB11 = Split(B) 60 | M1 = StrassenAlgorithm(MatrixPlus(AA00, AA11), MatrixPlus(BB00, BB11)) 61 | M2 = StrassenAlgorithm(MatrixPlus(AA10, AA11), BB00) 62 | M3 = StrassenAlgorithm(AA00, MatrixMinus(BB01, BB11)) 63 | M4 = StrassenAlgorithm(AA11, MatrixMinus(BB10, BB00)) 64 | M5 = StrassenAlgorithm(MatrixPlus(AA00, AA01), BB11) 65 | M6 = StrassenAlgorithm(MatrixMinus(AA10, AA00), MatrixPlus(BB00, BB01)) 66 | M7 = StrassenAlgorithm(MatrixMinus(AA01, AA11), MatrixPlus(BB10, BB11)) 67 | CC00 = MatrixPlus(MatrixMinus(MatrixPlus(M1, M4), M5), M7) 68 | CC01 = MatrixPlus(M3, M5) 69 | CC10 = MatrixPlus(M2, M4) 70 | CC11 = MatrixPlus(MatrixPlus(MatrixMinus(M1, M2), M3), M6) 71 | return Merge(CC00, CC01, CC10, CC11) 72 | 73 | 74 | s = pow(2, random.randint(1, 6)) 75 | m1 = [[random.randint(2, 100) for i in range(s)] for i in range(s)] 76 | m2 = [[random.randint(2, 100) for i in range(s)] for i in range(s)] 77 | print "Now displaying StrassenAlgorithm." 78 | m = StrassenAlgorithm(m1, m2) 79 | print StrassenAlgorithm(m1, m2) 80 | print MatrixMultiply(m1, m2) 81 | -------------------------------------------------------------------------------- /RedBlackTree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, key, left=None, right=None, color=None, p=None): 3 | self.left = left 4 | self.right = right 5 | self.color = color 6 | self.key = key 7 | self.p = p 8 | if key == "NIL": 9 | self.p = self 10 | 11 | def LeftRotate(self, T, x): 12 | y = x.right 13 | x.right = y.left 14 | if y.left != T.nil: 15 | y.left.p = x 16 | y.p = x.p 17 | if x.p == T.nil: 18 | T.root = y 19 | elif x == x.p.left: 20 | x.p.left = y 21 | else: 22 | x.p.right = y 23 | y.left = x 24 | x.p = y 25 | 26 | def RightRotate(self, T, x): 27 | y = x.left 28 | x.left = y.right 29 | if y.right != T.nil: 30 | y.right.p = x 31 | y.p = x.p 32 | if x.p == T.nil: 33 | T.root = y 34 | elif x == x.p.left: 35 | x.p.left = y 36 | else: 37 | x.p.right = y 38 | y.right = x 39 | x.p = y 40 | 41 | def RBInsert(self, T, z): 42 | y = T.nil 43 | x = T.root 44 | while x != T.nil: 45 | y = x 46 | if z.key < x.key: 47 | x = x.left 48 | else: 49 | x = x.right 50 | z.p = y 51 | if y == T.nil: 52 | T.root = z 53 | elif z.key < y.key: 54 | y.left = z 55 | else: 56 | y.right = z 57 | z.left = T.nil 58 | z.right = T.nil 59 | z.color = "RED" 60 | self.RBInsertFixUp(T, z) 61 | 62 | def TreeHeight(self, T, z): 63 | if z == T.nil: 64 | return 0 65 | lh = self.TreeHeight(T, z.left) 66 | rh = self.TreeHeight(T, z.right) 67 | if lh > rh: 68 | return lh + 1 69 | return rh + 1 70 | 71 | def RBInsertFixUp(self, T, z): 72 | while z.p.color == "RED": 73 | if z.p == z.p.p.left: 74 | y = z.p.p.right 75 | if y.color == "RED": 76 | z.p.color = "BLACK" 77 | y.color = "BLACK" 78 | z.p.p.color = "RED" 79 | z = z.p.p 80 | elif z == z.p.right: 81 | z = z.p 82 | self.LeftRotate(T, z) 83 | z.p.color = "BLACK" 84 | if z.p.p != T.nil: 85 | z.p.p.color = "RED" 86 | self.RightRotate(T, z.p.p) 87 | else: 88 | y = z.p.p.left 89 | if y.color == "RED": 90 | z.p.color = "BLACK" 91 | y.color = "BLACK" 92 | z.p.p.color = "RED" 93 | z = z.p.p 94 | elif z == z.p.left: 95 | z = z.p 96 | self.RightRotate(T, z) 97 | z.p.color = "BLACK" 98 | if z.p.p != T.nil: 99 | z.p.p.color = "RED" 100 | self.LeftRotate(T, z.p.p) 101 | T.root.color = "BLACK" 102 | 103 | def RBTransplant(self, T, u, v): 104 | if u.p == T.nil: 105 | T.root = v 106 | elif u == u.p.left: 107 | u.p.left = v 108 | else: 109 | u.p.right = v 110 | v.p = u.p 111 | 112 | def TreeMinimum(self, T, z): 113 | if z.left != T.nil: 114 | return self.TreeMinimum(T, z.left) 115 | else: 116 | return z 117 | 118 | def RBDeleteFixUp(self, T, x): 119 | while x != T.root and x.color == "BLACK": 120 | if x == x.p.left: 121 | w = x.p.right 122 | if w.color == "RED": 123 | w.color = "BLACK" 124 | x.p.color = "RED" 125 | self.LeftRotate(T, x.p) 126 | w = x.p.right 127 | if w !=T.nil : 128 | if w.left.color == "BLACK" and w.right.color == "BLACK": 129 | w.color = "RED" 130 | x = x.p 131 | elif w.right.color == "BLACK": 132 | w.left.color = "BLACK" 133 | w.color = "RED" 134 | self.RightRotate(T, w) 135 | w = x.p.right 136 | w.color = x.p.color 137 | x.p.color = "BLACK" 138 | w.right.color = "BLACK" 139 | self.LeftRotate(T, x.p) 140 | x = T.root 141 | else: 142 | w = x.p.left 143 | if w.color == "RED": 144 | w.color = "BLACK" 145 | x.p.color = "RED" 146 | self.RightRotate(T, x.p) 147 | w = x.p.left 148 | if w.right.color == "BLACK" and w.left.color == "BLACK": 149 | w.color = "RED" 150 | x = x.p 151 | elif w.left.color == "BLACK": 152 | w.right.color = "BLACK" 153 | w.color = "RED" 154 | self.LeftRotate(T, w) 155 | w = x.p.left 156 | w.color = x.p.color 157 | x.p.color = "BLACK" 158 | w.left.color = "BLACK" 159 | self.RightRotate(T, x.p) 160 | x = T.root 161 | x.color = "BLACK" 162 | 163 | def RBDelete(self, T, z): 164 | y = z 165 | yOriginalColor = y.color 166 | if z.left == T.nil: 167 | x = z.right 168 | self.RBTransplant(T, z, z.right) 169 | elif z.right == T.nil: 170 | x = z.left 171 | self.RBTransplant(T, z, z.left) 172 | else: 173 | y = self.TreeMinimum(T, z.right) 174 | yOriginalColor = y.color 175 | x = y.right 176 | if y.p == z: 177 | x.p = y 178 | else: 179 | self.RBTransplant(T, y, y.right) 180 | y.right = z.right 181 | y.right.p = y 182 | self.RBTransplant(T, z, y) 183 | y.left = z.left 184 | y.left.p = y 185 | y.color = z.color 186 | if yOriginalColor == "BLACK": 187 | self.RBDeleteFixUp(T, x) 188 | 189 | def InOrderTraversal(self, T, s, A): 190 | if s == T.nil : 191 | return 192 | if s.left != T.nil: 193 | self.InOrderTraversal(T, s.left, A) 194 | A.append(s) 195 | if s.right != T.nil: 196 | self.InOrderTraversal(T, s.right, A) 197 | 198 | 199 | class Tree: 200 | def __init__(self): 201 | nil = Node("NIL", color="BLACK") 202 | self.root = nil 203 | self.nil = nil 204 | 205 | 206 | T = Tree() 207 | B = [11, 2, 14, 1, 7, 15, 5, 8, 4] 208 | BB = [26] 209 | for j in B: 210 | T.root.RBInsert(T, Node(j)) 211 | print j 212 | A = [] 213 | T.root.InOrderTraversal(T, T.root, A) 214 | for i in A: 215 | T.root.RBDelete(T, i) 216 | AA = [] 217 | T.root.InOrderTraversal(T, T.root, AA) 218 | print "AfterDeleting ", i.key, ".Nodes in tree:", [AAA.key for AAA in AA] 219 | --------------------------------------------------------------------------------