├── .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 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
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 |
10 |
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 |
--------------------------------------------------------------------------------