diff --git a/README.md b/README.md index c4e58ec..372e16d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ algorithm ========= -在阅读算法导论的时候。我用Python写的一些算法,这些算法大部分使用list来作为底层存储数据的结构。但是python的list用的是链表实现,因此有些操作性能不高。 +在阅读算法导论的时候。我用Python写的一些算法,这些算法大部分使用list来作为底层存储数据的结构。 #算法 ##排序算法:sort文件夹下面 diff --git a/src/ssj/graph/__init__.py b/src/ssj/graph/__init__.py index fb57e2f..b91606e 100644 --- a/src/ssj/graph/__init__.py +++ b/src/ssj/graph/__init__.py @@ -1,3 +1,7 @@ #!/usr/bin/env python # -*- coding:UTF-8 __author__ = 'shenshijun' + + +class GraphError(StandardError): + pass diff --git a/src/ssj/graph/digraph.py b/src/ssj/graph/digraph.py new file mode 100644 index 0000000..2e32c4d --- /dev/null +++ b/src/ssj/graph/digraph.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python +# -*- coding:UTF-8 + +__author__ = 'shenshijun' +from ssj.lib.queue import Queue +from ssj.graph import GraphError + + +class Vertex(object): + def __init__(self, key, weight=None): + """ + adjust_list 表示邻接节点 + """ + self.key = key + self.weight_list = [] + self.adjust_list = [] + self.in_degree = 0 + self.backup_in_degree = self.in_degree + self.out_degree = 0 + self.backup_out_degree = self.out_degree + self.dist = 0 + + def add_adjust(self, to_vertex): + self.adjust_list.append(to_vertex) + self.out_degree += 1 + self.backup_out_degree += 1 + + +class Digraph(object): + def __init__(self): + self._vertexes = {} + + def add_vertex(self, key): + """ + Args: + :param key:顶点关键字 + Returns: + :rtype: bool + """ + if key in self._vertexes: + return False + else: + self._vertexes[key] = Vertex(key) + return True + + def add_edge(self, from_key, to_key): + # 首先把两个节点查入到图中 + self.add_vertex(from_key) + self.add_vertex(to_key) + self._vertexes[from_key].add_adjust(self._vertexes[to_key]) + self._vertexes[to_key].in_degree += 1 + self._vertexes[to_key].backup_in_degree += 1 + + def top_sort(self, func): + zero_in_degree_queue = Queue() + + # 首先找到所有入度为0的顶点,遍历从这里开始 + for key, vertex in self._vertexes.iteritems(): + vertex.backup_in_degree = vertex.in_degree + if vertex.in_degree is 0: + zero_in_degree_queue.enter(vertex) + + if zero_in_degree_queue.empty(): + raise GraphError('图中有环,无法执行图的拓扑排序') + + result = [] + while not zero_in_degree_queue.empty(): + zero_vertex = zero_in_degree_queue.exit() + result.append(func(zero_vertex.key)) + for vertex in zero_vertex.adjust_list: + vertex.in_degree -= 1 + if vertex.in_degree is 0: + zero_in_degree_queue.enter(vertex) + + # 恢复 + for key, vertex in self._vertexes.iteritems(): + vertex.in_degree = vertex.backup_in_degree + return result + + def bfs(self, key, func): + next_vertex_queue = Queue() + for k, vertex in self._vertexes.iteritems(): + vertex.dist = -1 + + result = [] + self._vertexes[key].dist = 0 + next_vertex_queue.enter(self._vertexes[key]) + + while not next_vertex_queue.empty(): + vertex = next_vertex_queue.exit() + result.append(func(vertex.key, vertex.dist)) + for adjust_vertex in vertex.adjust_list: + if adjust_vertex.dist is -1: + adjust_vertex.dist = vertex.dist + 1 + next_vertex_queue.enter(adjust_vertex) + + for k, vertex in self._vertexes.iteritems(): + if vertex.dist is -1: + result.extend(self.bfs(vertex.key, func)) + return result + + +def main(): + graph = Digraph() + graph.add_edge('v1', 'v2') + graph.add_edge('v1', 'v3') + graph.add_edge('v1', 'v4') + graph.add_edge('v2', 'v4') + graph.add_edge('v4', 'v3') + graph.add_edge('v4', 'v7') + graph.add_edge('v4', 'v6') + graph.add_edge('v3', 'v6') + graph.add_edge('v2', 'v5') + graph.add_edge('v5', 'v4') + graph.add_edge('v5', 'v7') + graph.add_edge('v7', 'v6') + print graph.top_sort(lambda key: key) + print graph.bfs('v1', lambda key, dist: (key, dist)) + + +if __name__ == "__main__": + main() diff --git a/src/ssj/graph/general_graph.py b/src/ssj/graph/general_graph.py deleted file mode 100644 index 8bc02f8..0000000 --- a/src/ssj/graph/general_graph.py +++ /dev/null @@ -1,189 +0,0 @@ -#!/usr/bin/env python -# -*- coding:UTF-8 - -import sys -from ssj.lib.stack import Stack - -reload(sys) -sys.setdefaultencoding('UTF-8') - - -__author__ = 'shenshijun' - - -class Node(object): - """ - 图中存储数据的结点 - """ - - def __init__(self, key, color): - """ - color - -1:白色 - 0:灰色 - 1:黑色 - """ - - self.key = key - self.color = color - self.depth = 0 - self.parent = None - self.start_time = None - self.end_time = None - - def set_gray(self): - self.color = 0 - - def set_black(self): - self.color = 1 - - def set_white(self): - self.color = -1 - - def is_gray(self): - return self.color is 0 - - def is_white(self): - return self.color is -1 - - def is_black(self): - return self.color is 1 - - def __eq__(self, other): - return self.key == other.key and self.color == other.color and self.depth == other.depth - - def __str__(self): - return "".join(['Node(key=', unicode(self.key), - ',depth=', str(self.depth), ',start_time=', str(self.start_time), ',end_time=', - str(self.end_time), - ',color:', 'white' if self.color is -1 else 'gray' if self.color is 0 else 'black', ')']) - - -class GeneralGraph(object): - """ - 使用邻接链表法存储一个通用的图结构。 - 使用一个元组来表示一个图中的边 - 要注意一个实现上的问题:邻接链表中的元素和关键字元素必须指向同一个对象 - """ - - def __init__(self, *vargs): - """ """ - self.__dict = {} - map(self.insert, vargs) - - def insert(self, edge): - start_node = self.__find(edge[0]) - end_node = self.__find(edge[1]) - linked_node = self.__dict.setdefault(start_node, []) - linked_node.append(end_node) - - def delete_edge(self, edge): - start_node = self.__find(edge[0]) - linked_list = self.__dict.get(start_node, []) - for x in xrange(0, len(linked_list)): - if linked_list[x].key == edge[1]: - del linked_list[x] - return True - return False - - def __find(self, instance): - for key_node in self.__dict.iterkeys(): - if key_node.key == instance: - return key_node - node = Node(instance, -1) - self.__dict[node] = [] - return node - - def bfs(self, instance, gray_func, black_func): - """ - 图的广度遍历 - :param gray_func:当节点在灰色的时候遍历的函数 - :param black_func:当节点在黑色的时候执行的函数 - :return:结果 - """ - gray_list = [] - black_list = [] - node = self.__find(instance) - if node is None: - return None - graph_queue = queue.Queue() - # 初始化节点 - node.set_white() - node.depth = 0 - node.parent = None - for end_node in self.__dict.iterkeys(): - end_node.set_white() - end_node.depth = 0 - end_node.parent = Node - - # 开始遍历 - node.set_gray() - graph_queue.enter(node) - while not graph_queue.empty(): - cur_node = graph_queue.exit() - gray_list.append(gray_func(cur_node)) - for end_node in self.__dict[cur_node]: - if end_node.is_white(): - end_node.set_gray() - end_node.depth += cur_node.depth - end_node.parent = cur_node - graph_queue.enter(end_node) - cur_node.set_black() - black_list.append(black_func(cur_node)) - return gray_list, black_list - - def dfs(self, gray_func, black_func): - """ - 图的深度遍历 - :param gray_func: - :param black_func: - :return: - """ - gray_list = [] - black_list = [] - - # 初始化 - for key in self.__dict.iterkeys(): - key.start_time = None - key.end_time = None - key.set_white() - - # 开始遍历 - counter = 0 - for key in self.__dict.iterkeys(): - if key.is_white(): - dfs_stack = Stack() - key.set_gray() - key.start_time = counter - counter += 1 - dfs_stack.push(key) - while not dfs_stack.empty(): - cur_node = dfs_stack.pop() - gray_list.append(gray_func(key)) - for end_node in self.__dict[cur_node]: - if end_node.is_white(): - end_node.set_gray() - end_node.start_time = counter - counter += 1 - dfs_stack.push(end_node) - cur_node.set_black() - black_list.append(black_func(cur_node)) - cur_node.end_time = counter - counter += 1 - return gray_list, black_list - - def topology_sort(self): - gray_list, black_list = self.dfs(lambda node: node, lambda node: node) - return reversed(black_list) - - -def main(): - graph = GeneralGraph(('内裤', '鞋'), ('内裤', '裤子'), ('裤子', '腰带'), ('腰带', '夹克'), ('衬衣', '腰带'), ('衬衣', '领带'), ('袜子', '鞋'), - ('手表', '手表')) - gray_list, black_list = graph.dfs(lambda node: str(node), lambda node: str(node)) - print gray_list - print black_list - - -if __name__ == "__main__": - main() diff --git a/src/ssj/heap/fibonacci_heap.py b/src/ssj/heap/fibonacci_heap.py index cdc38b5..7a90dc1 100644 --- a/src/ssj/heap/fibonacci_heap.py +++ b/src/ssj/heap/fibonacci_heap.py @@ -4,7 +4,7 @@ class FibonacciHeap(object): - """实现斐波那契堆,斐波那契堆在一些操作执行的时候负责度比较低,而其他操作的复杂度和普通的堆是一样的""" + """实现斐波那契堆,斐波那契堆在一些操作执行的时候复杂度比较低,而其他操作的复杂度和普通的堆是一样的""" class Node(object): """节点实现""" diff --git a/src/ssj/tree/avl_tree.py b/src/ssj/tree/avl_tree.py new file mode 100644 index 0000000..1f3a1f6 --- /dev/null +++ b/src/ssj/tree/avl_tree.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding:UTF-8 +__author__ = 'shenshijun' + +""" +定义: +AVL树是高度平衡的二叉搜索树,平衡的方式是每一个节点左右子树高度差顶多为1. +每一个节点中会存储这个节点的高度。节点高度是指从这个节点到叶节点的最大距离。 + +高度: +AVL树的高度大约是1.44log(N)。 +高度为n的AVL树的最小节点数:s(h)=s(h-1)+s(h-2)+1 +""" + + +class Node(object): + """""" + + def __init__(self, value, parent, left, right, height=0): + """Constructor for Node""" + self.value = value + self.height = height + self.parent = parent + self.left = left + self.right = right + + +class AVLTree(object): + """""" + + def __init__(self): + """Constructor for """ + self.__root = None + self.__size = 0 + + def insert(self, value): + pass diff --git a/src/ssj/tree/avltree.py b/src/ssj/tree/avltree.py deleted file mode 100644 index 8d24c9b..0000000 --- a/src/ssj/tree/avltree.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python -# -*- coding:UTF-8 -__author__ = 'shenshijun' - - -class AVLTree(object): - """""" - - def __init__(self): - """Constructor for """ - pass diff --git a/src/ssj/tree/binarystree.py b/src/ssj/tree/binary_search_tree.py similarity index 100% rename from src/ssj/tree/binarystree.py rename to src/ssj/tree/binary_search_tree.py diff --git a/src/ssj/tree/binarytree.py b/src/ssj/tree/binary_tree.py similarity index 100% rename from src/ssj/tree/binarytree.py rename to src/ssj/tree/binary_tree.py diff --git a/src/ssj/tree/bplus_tree.py b/src/ssj/tree/bplus_tree.py new file mode 100644 index 0000000..427d393 --- /dev/null +++ b/src/ssj/tree/bplus_tree.py @@ -0,0 +1,6 @@ +# TODO实现B+树 +class BplusTree: + def __init__(self): + pass + + pass diff --git a/src/ssj/tree/tries.py b/src/ssj/tree/tries.py index 1dc2140..6a267bf 100644 --- a/src/ssj/tree/tries.py +++ b/src/ssj/tree/tries.py @@ -3,6 +3,7 @@ __author__ = 'shenshijun' +# TODO实现 class Tries(object): """ 字符串前缀树实现