随笔分类 - 数据结构与算法--Python实现
1
摘要:LRU是Least Recently Used的缩写,即最近最少使用,常用于页面置换算法,是为虚拟页式存储管理服务的。 现代操作系统提供了一种对主存的抽象概念虚拟内存,来对主存进行更好地管理。他将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在主存和磁盘之间来回传
阅读全文
摘要:一个无向图G的最小生成树就是由该图的那些连接了G的所有顶点的边构成的树,且其总权重最低。最小生成树存在当且仅当G是连通的。对于任何一生成树T,如果将一条不属于T的边e加进来,则产生一个圈。如果从圈中除去任意一条边,则又恢复树的特性。如果边e的权值比除去的边的值低,那么新生成的树的值就比原生成的树的值...
阅读全文
摘要:Dijkstra算法解决了有向图G=(V,E)上带权的单源最短路径问题,但要求所有边的权值非负。Dijkstra算法是贪婪算法的一个很好的例子。设置一顶点集合S,从源点s到集合中的顶点的最终最短路径的权值均已确定。算法反复选择具有最短路径估计的顶点u,并将u加入到S中,对u的所有出边进行松弛。如果可...
阅读全文
摘要:有一个无权的图G,使用某个顶点s作为输入参数,找出从s到其它顶点的最短路径。这样,只要计算包含在路径中的边数就可以了。比如,一个word ladder problem,一次只变换一个字母,找出从fool到sage的最短路径。可用的单词可以转化为一个图:首先寻找与fool距离为1的顶点:然后可以寻找距...
阅读全文
摘要:拓扑排序是对有向无圈图的顶点的一种排序。如果存在一条vi到vj的路径,则vi排在vj前面。如果图含有圈,则拓扑排序是不可能的。拓扑排序的两种排法:一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后显示出该顶点,并将它和它的边一起从图中删除,对图的其余部分应用同样的方法。首先,对于每个顶点...
阅读全文
摘要:一个图(graph)G=(V,E)是由顶点集V和边集E组成。每一条边就是一个顶点对(v,w),其中v,w∈V。如果点对是有序的,那么图就是有向图。图中的一条路径path是一个顶点序列w1,w2,w3,...,wk,使得(wi,wi+1)∈E,1<=i<=k。路径的长是该路径上的边数。 如果在一个无...
阅读全文
摘要:不相交集合数据结构保持一组不相交的动态集合S={S1,S2,...,SK},每个集合通过一个代表来识别,代表即集合中的某个成员。如果x表示一个对象,不相交集合支持以下操作:MAKE-SET(x):建立一个新的集合,其唯一成员为x。因为各集合是不想交的,故x没有在其它集合中出现。UNION(x,y):...
阅读全文
摘要:排序是算法学习中最基本的问题。1.平均时间复杂度均为O(N2)的排序1.1 插入排序插入排序对少量元素的排序非常有效。工作机制就像打牌一样,为了将牌插入到已排好序的牌中,需要将牌与手中的牌从右向左进行比较。def insertionSort(alist): n=len(alist) fo...
阅读全文
摘要:优先队列(priority queue)是允许至少两种操作的数据结构:Insert及DeleteMin(删除最小者)。相当于队列中的Enqueue、Dequeue操作。优先队列可以用链表、二叉查找树、二叉堆等实现。二叉堆1. 结构性质堆(heap)是一棵完全被填满的二叉树,有可能的例外是在底层,底层...
阅读全文
摘要:散列表的实现常常叫做散列(hashing)。散列仅支持INSERT,SEARCH和DELETE操作,都是在常数平均时间执行的。需要元素间任何排序信息的操作将不会得到有效的支持。散列表是普通数组概念的推广。如果空间允许,可以提供一个数组,为每个可能的关键字保留一个位置,就可以运用直接寻址技术。当实际存...
阅读全文
摘要:设计包含min函数的栈。定义栈的数据结构,要求添加一个min函数,能够得到栈的最小元素。要求函数min、push以及pop的时间复杂度都是O(1)。栈中元素设两个域,一个记录元素的值,一个记录栈的最小值。class Stack(object): def __init__(self): ...
阅读全文
摘要:B树(或称B-树)是一种适用于外查找的树,它是一种平衡的多叉树。阶为M的B树具有下列结构特征:1.树的根或者是一片树叶,或者其儿子数在2和M之间。2.除根节点外的所有非树叶节点儿子数在┌M/2┐和 M之间。3.所有的树叶都在相同的高度。4.节点中包括n个关键字,n+1个指针,一般形式为: (n,P0...
阅读全文
摘要:题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。 比如将二元查找树10/ \6 14/ \ / \4 8 12 16转换成双向链表4=6=8=10=12=14=16。一道微软的面试题。二叉查找树的每个节点都有两个指针,双向链表的节点也...
阅读全文
摘要:AVL树是带有平衡条件的二叉查找树,一般要求每个节点的左子树和右子树的高度最多差1(空树的高度定义为-1)。在高度为h的AVL树中,最少的节点数S(h)由S(h)=S(h-1)+S(h-2)+1得出,其中S(0)=1,S(1)=2。如上图,分别为高度为0,1,2,3的AVL树所需要的最少节点数。1.AVL树的实现,遍历与查找操作与二叉查找树相同。class Node(object): def __init__(self,key): self.key=key self.left=None self.right=None self.he...
阅读全文
摘要:对于二叉查找树的每个节点Node,它的左子树中所有的关键字都小于Node的关键字,而右子树中的所有关键字都大于Node的关键字。二叉查找树的平均深度是O(log N)。1.初始化class BinarySearchTree(object): def __init__(self,key): self.key=key self.left=None self.right=None2.Find def find(self,x): if x==self.key: return self elif xs...
阅读全文
摘要:1. 二叉树二叉树(binary tree)中的每个节点都不能有多于两个的儿子。1.1 二叉树列表实现如上图的二叉树可用列表表示:tree=['A', #root ['B', #左子树 ['D',[],[]], ['E',[],[]]], ['C', #右子树 ['F',[],[]], []] ]实现:def BinaryTree(item): return [item,[],[]]def insertLeft(tree,item): leftSubtree=tree.pop(1) ...
阅读全文
摘要:1. 一个列表实现两个栈class Twostacks(object): def __init__(self): self.stack=[] self.a_size=0 self.b_size=0 self.top=0 def a_isEmpty(self): return self.a_size==0 def a_push(self,item): self.stack.insert(self.a_size,item) self.a_size+=1 def ...
阅读全文
摘要:1. 栈栈(Stack)是限制插入和删除操作只能在一个位置进行的表,该位置是表的末端,称为栈的顶(top)。栈的基本操作有PUSH(入栈)和POP(出栈)。栈又被称为LIFO(后入先出)表。1.1 栈的实现class Stack(object): def __init__(self): self.stack=[] def isEmpty(self): return self.stack==[] def push(self,item): self.stack.append(item) def pop(self): i...
阅读全文
摘要:1. 桶排序1.1 范围为1-M的桶排序如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort)。留置一个数组S,里面含有M个桶,初始化为0。然后遍历数组A,读入Ai时,S[Ai]增一。所有输入被读进后,扫描数组S得出排好序的表。该算法时间花费O(...
阅读全文
摘要:链表由一系列不必在内存中相连的结构构成,这些对象按线性顺序排序。每个结构含有表元素和指向后继元素的指针。最后一个单元的指针指向NULL。为了方便链表的删除与插入操作,可以为链表添加一个表头。删除操作可以通过修改一个指针来实现。插入操作需要执行两次指针调整。1. 单向链表的实现1.1 Node实现 每个Node分为两部分。一部分含有链表的元素,可以称为数据域;另一部分为一指针,指向下一个Node。class Node(): __slots__=['_item','_next'] #限定Node实例的属性 def __init__(self,item): self.
阅读全文
1