算法与数据结构(python实现)
文章平均质量分 96
不吃鱼的猫748
这个作者很懒,什么都没留下…
展开
-
四种不同的列表构造方法的时间复杂度比较
先附上代码import timeimport matplotlib.pyplot as pltdef test1(n): lst=[] for i in range(n*10000): lst+=[i] return lstdef test2(n): lst=[] for i in range(n*10000): ...原创 2018-10-16 12:12:05 · 675 阅读 · 0 评论 -
二叉树(python实现)
二叉树是一种简单的树形结构,其每个节点的分支节点数有0,1或2个。如下图T1,T2和T3是三棵二叉树。显然二叉树是一种递归的结构。 不包含任何节点的二叉树为空树,只有一个节点的二叉树称为单点树,一个节点的子节点的个数称为该节点的度。如果每个分支节点的度都为2,则称之为满二叉树。T4,T5就是两棵满二叉树。如果一棵二叉树,除最后一层外,其它层的节点都是满的,而最后一层节点在最左边连续...原创 2018-11-16 20:27:49 · 10718 阅读 · 0 评论 -
哈夫曼树与哈夫曼算法(python实现)
哈夫曼树定义设有实数集,T是一棵扩充二叉树,其m个外部结点分别以wi(i=1,2,..,n-1)为权,而且T的带权外部路径长度在所有这样的扩充二叉树中达到最小,则称T为数据集的最优二叉树或者哈夫曼树。哈夫曼算法以下以一个例子演示了哈夫曼算法的过程。由于构造哈夫曼树的过程中每次要取根节点较小的 两棵树生成重新一棵树,因此可以考虑使用优先队列存储这些待处理的树。因为优先队列...原创 2018-11-16 21:25:57 · 3894 阅读 · 0 评论 -
最小生成树算法(python实现)
Kruskal算法Kruskal算法是一种构造最小生成树的简单算法,其中的思想比较简单。基本思想设G=(V,E)是一个网络,其中|V|=n。Kruskal算法构造最小生成树的过程是:初始时取包含G中所有n个顶点但没有任何边的孤立点子图T=(V,{}),T里的每个顶点自成一个连通分量。下面将通过不断扩充T的方式构造G的最小生成树。 将边集E中的边按权值递增的顺序排序,在构造中的每一步顺序...原创 2018-11-26 12:30:57 · 15320 阅读 · 0 评论 -
图的非递归深度优先遍历算法的python实现
采用深度优先遍历方式处理一个图,也就是按照深度优先搜索(Depth-FirstSearch)的方式实施整个遍历过程。假定从指定顶点v出发,深度优先遍历的做法是:首先访问顶点并将其标记为已访问。 检查v的邻接顶点,从中选一个尚未访问的顶点,从它出发继续进行深度优先搜索(这是递归)。不存在这种邻接顶点时回溯(邻接顶点可能排了一种顺序)。 反复上述操作直到从v出发可达的所有顶点都已访问(递归)。...原创 2018-11-25 14:25:40 · 2492 阅读 · 0 评论 -
递归方式构造DFS生成树(python实现)
从连通无向图或强连通有向图中任一顶点出发遍历,或从有根有向图的根顶点出发遍历,都可以访问到所有顶点。在遍历中经过的边加上原图的所有顶点,就构成该图的一棵生成树。通过遍历构造生成树的过程可以按深度优先方式或宽度优先方式进行,在遍历中记录访问的所有顶点和经过的边,就得到原图的深度优先生成树(简称DFS生成树),或者宽度优先生成树(BFS生成树)。在得到的生成树中,每个节点可能有多个后一节点,但都有...原创 2018-11-25 15:55:28 · 3135 阅读 · 0 评论 -
Dijkstra算法
Dijkstra算法(迪杰斯特拉算法,D算法)可以求出一个给定顶点到图中所有其他顶点的最短路径。Dijkstra算法的限制是要求图中所有边的权值不小于0。算法思路Dijkstra算法是依据最短路径的最优子结构性质来进行的,抓住这一点就可以很好的理解Dijkstra算法。该性质描述为:如果P(i,j)={Vi....Vk..Vs...Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中...原创 2018-11-28 15:15:10 · 634 阅读 · 0 评论 -
弗洛伊德(Floyd)算法
弗洛伊德(Floyd)算法可求解任意顶点间的最短路径。在Floyd算法中,需要两个矩阵,一个是邻接矩阵A,最开始,A[i][j]的值为节点i到节点j的边的权值,如果i到j没有边,A[i][j]=,特别地,A[i][i]=0。另一个矩阵为P,P[i][j]的值为从i到j的路径上节点i的下一个节点,通过该矩阵可以找出任意节点i到节点j的最短路径。最开始,若i与相邻,则P[i][j]=j,否则P[i...原创 2018-11-28 17:33:51 · 750 阅读 · 0 评论 -
AOV网络、拓扑排序、拓扑序列
AOV网络AOV网是有向图的一类应用,在AOV网中,用顶点表示某个有一定规模的“工程”里的不同活动,用图中的边表示各项活动之间的先后顺序关系。一种常见的AOV网实例是大学课程的先修关系,以下表格列出了计算机专业若干课程及其先修课程:课程编号 课程名称 先修课程 C1 高等数学 C2 程序设计基础 C3 数据结构 C1,C2...原创 2018-12-07 14:51:14 · 10041 阅读 · 0 评论 -
AOE网和关键路径
AOE网抽象地看,AOE网是一种无环的带权有向图,其中:顶点表示事件,有向边表示活动,边上的权值通常表示活动的持续时间。 图中一个顶点表示的事件,也就是它的人边所表示的活动都已完成,它的出边所表示的活动可以开始的那个状态,把这一情况看作事件。实际工程或复杂事务里的一批相关活动(工作项目、任务等),可以用一个AOE网描述(抽象),然后就可以基于这个网考虑活动的安排了。 下图给出的AO...原创 2018-12-07 16:25:32 · 6432 阅读 · 0 评论 -
图结构的python实现
图是一种非线性的关系型数据结构,关于图的概念以及性质网络上已有很多资料,我不再多说。本文主要介绍两种基于python的图结构的实现方法。邻接矩阵实现邻接矩阵是表示图中顶点间邻接关系的方阵。对于n个顶点的图G=(V,E),其邻接矩阵是一个的方阵,图中每个顶点(按顺序)对应于矩阵里的一行和一列,矩阵元素表示图中的邻接关系。一般对于不带权值的图,用1表示节点有边,用0表示节点无边。对于有权图...原创 2018-11-18 18:16:12 · 17418 阅读 · 0 评论 -
堆排序(python实现)
对于堆的概念以及它的一些基本操作,请参见我的上一篇博客。利用堆实现排序的简单思路是,利用堆顶元素总是最大或者最小的性质,每次弹出一个元素,直到堆空,则弹出元素形成的序列是有序的。但是为了节约存储空间,我们直接将弹出的元素放在原堆内存的后面,这样形成的最后形成的有序数组的顺序是和堆中数据的顺序性是相反的(若是小根堆,排序后是由大到小的;若是大根堆,排序后是由小到大的)。代码如下所示def ...原创 2018-11-08 21:19:41 · 248 阅读 · 0 评论 -
用python实现堆
堆是一种数据结构,它是一棵完全二叉树,且某个节点的值总是不大于或不小于其父节点的值;根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。根据完全二叉树的性质,若将堆中的数据至顶向下,从左向右的存在一个一维数组里面,则父节点的位置索引总是该节点位置索引减1再除2取整的结果,如下图所示。 若直接将一组数如 [8,5,2,9,3,7,1,4,6] 放入上图所示的二叉树(如下图),...原创 2018-11-08 20:14:27 · 1466 阅读 · 0 评论 -
单链表的设计与改进、循环链表(python实现)
#节点类class LNode: def __init__(self,elem,next_=None): self.elem=elem self.next=next_#自定义异常,在链表为空时访问元素抛出class LinkListUnderflow(ValueError): pass#单链表类class LList: def...原创 2018-10-16 18:32:40 · 421 阅读 · 0 评论 -
双链表(python实现)
双链表的每个节点都有两个指针域,分别指向它的前一个节点和后一个节点,因此在双链表中插入和删除节点要考虑到这两个指针域的变动。也正是由于双链表节点的双向引用特点,使得在链表尾部插入和删除节点的操作性能得到了改善。双链表的节点删除本文实现的双链表结构如下图所示,即带有尾节点引用域的双链表结构。 class DLNode: #双链表节点类 def __init__(sel...原创 2018-10-20 00:25:36 · 232 阅读 · 0 评论 -
队列的顺序表实现(python实现)
队列是一种先进先出(FIFO)的数据结构,因此对队列的操作涉及到队列的头部和尾部。若用python中的顺序表(list)实现,出队用pop(0),入队用append()实现,则删除list头部数据的开小较大,不是一种高效的实现。但可是使用list作为储存队列的空间,实现队列需要一个头部元素位置的引用,以及当前队列的长度。具体实现原理如下: 由上图可以总结出实现的思路:用一个固定大小的列...原创 2018-10-28 19:16:34 · 1259 阅读 · 0 评论 -
两种链表操作--链表反转、链表排序(pyhon实现)
链表反转和链表排序是两种链表的基本操作,在python里list类型的reverse()方法就是对list的反转,sort()方法可以对list的元素进行排序,本文将探讨这两种链表操作基于单链表的实现方式。 链表反转对于单链表而言,链表反转可以有两种实现方式,一种是在节点之间搬动元素,即往复地将尾部元素搬到头部;另一种是修改节点的连接关系,通过改变节点的连接顺序来改表元素的顺序。但是单...原创 2018-10-21 14:55:04 · 265 阅读 · 0 评论 -
栈的两种实现方式(python实现)
栈是一种后进先出(LIFO)的数据结构,在设计算法时有十分广泛的应用。对栈的操作是通过将元素压入栈(放在栈顶),或是将栈顶元素弹出,都是对栈顶元素的操作。若要实现一个高效的栈,则要考虑到这两种操作的时间复杂度。 有两种数据结构可以作为实现栈的基础:顺序表和链表。在顺序表尾端插入或删除元素的时间复杂度与在链表头部插入和删除元素的时间复杂度都是O(1),因此可以考虑将顺序表尾部或链表...原创 2018-10-27 17:16:24 · 1266 阅读 · 0 评论 -
栈的应用之括号匹配
在许多正文中都有括号,特别是在表示程序、数学表达式的正文片段里,括号有正确配对问题。作为例子,下面考虑python程序里的括号,在这里可以看到:存在多种不同的括号,下面只考虑其中三种:圆括号、方括号和花括号。 每种括号都包括一个开括号和一个闭括号,相互对应。括号括起的片段可能嵌套,各种括号应该正确地嵌套并分别配对。不难总结出检查括号配对的原则:在扫描正文过程中,遇到的闭括号应该与此前最近遇...原创 2018-10-27 18:46:06 · 230 阅读 · 0 评论 -
栈的应用之后缀表达式求值
后缀表达式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。我们数学上采用的表达式叫中缀表达式,即将运算放在两个运算对象中间。此外还有后缀表达式,即将运算符放在两个运算对象的前面。下面是同一个算术表达式的三种等价表示形式:中缀形式:(3-5)*(6+17*4)/3前缀形式:/ * - 3 5 + 6 * 17 ...原创 2018-10-27 19:14:56 · 936 阅读 · 0 评论 -
栈的应用之中缀表达式转后缀表达式
由于中缀表达式有括号的存在,其运算次序比较复杂,直接分析有些难度。先考虑不带括号的中缀表达式的转换。由于运算符号具有不同的优先级,当前的运算符不能直接放在操作数的后面,需要考虑下一个运算符的优先级。对比三个不同的中缀表达式转换为后缀表达式的结果可以发现:1.后缀表达式数字的出现顺序和中缀表达式中是完全一样的。2.中缀表达式中相邻两个运算符的优先级不一样,其在后缀表达...原创 2018-10-27 20:39:40 · 389 阅读 · 0 评论 -
求解迷宫问题的三种方法(python实现)
在迷宫问题中,给定入口和出口,要求找到路径。本文将讨论三种求解方法,递归求解、回溯求解和队列求解。在介绍具体算法之前,先考虑将迷宫数字化。这里将迷宫用一个二维的list存储(即list嵌套在list里),将不可到达的位置用1表示,可到达的位置用0表示,并将已经到过的位置用2表示。递归求解递归求解的基本思路是:每个时刻总有一个当前位置,开始时这个位置是迷宫人口。 如果当前位置就...原创 2018-11-04 21:00:55 · 42732 阅读 · 0 评论 -
二叉排序树
定义二叉排序树是一种在结点里存储数据的二叉树。一棵二又排序树或者为空,或者具有下面的性质:其根结点保存着一个数据项(及其关键码)。 如果其左子树不空,那么其左子树的所有结点保存的(关键码)值均小于(如果不要求严格小于,也可以是“不大于")根结点保存的(关键码)值。 如果其右子树不空,那么其右子树的所有结点保存的(关犍码)值均大于它的根结点保存的(关犍码)值。 非空的左子树或右子树也是...原创 2018-12-17 16:36:17 · 42587 阅读 · 0 评论