算法与数据结构

【算法与数据结构】复杂度分析

拜拜、爱过 提交于 2019-12-09 21:36:41
本文记录了博主对算法复杂度分析,常见的几种复杂度,以及平均时间复杂度、最好/最坏时间复杂度的总结。 复杂度分析   关于算法的复杂度,我们通常采用大O来进行表示,在此我们假设每行代码的执行时间都一样,为一个单位时间,然后在这个假设的基础上进行时间、空间复杂度的分析。先分析一下上面的代码,2-4行的时间复杂度为3,紧接着有两个for循环,第一个for循环的时间复杂度为n,同时第6行的时间复杂度也为n,而内部的for循环的时间复杂度为2*n*n。总的时间复杂度则为2*n*n + 2*n+3。因此,此算法的时间复杂度为O(2*n*n + 2*n+3)。在此关于复杂度分析,有三点需要注意的:   1、 总的时间复杂度等于量级最大的那端代码的复杂度, 分析算法的时间复杂度的时候,常常忽略 常数阶 , 低阶 , 系数。因此分析一个算法的时间复杂度的时候,我们只需要关注量级最大的那段即可。    2、乘法规则: 嵌套的代码等于嵌套代码体内外执行时间的乘积 。我们可以发现在for循环的嵌套中,基本都采用了这个规则。 如下面这段代码,外部for循环的复杂度为O(3*n), 第2个for循环的复杂度则为O(2*n), 整个代码的时间复杂度为O(2*n)*O(n) + O(2*n) + 3;因此改代码的复杂度为O(n*n) 1 int cal(int n) { 2 int sum = 0; 3 int

数据结构与算法 试题2.7

我们两清 提交于 2019-12-09 20:36:21
数据结构与算法 2.7 习题2.7 假设需要生成前N个自然数的一个随机置换。例如,{3,4,1,5,2}和{5,2,3,1,4}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现了两次而数3却没有。 这个程序常用语模拟一些算法。我们假设存在一个随机数生成器RandInt(i,j),它以相同的概率生成i和j之间的一个整数。下面是三个算法: 如下填入从A[0]到A[N-1]的数组A;为了填入A[i],生成随机数直到它不同于生成的A[0],A[1]......A[i-1]时,在填入A[i] 同算法(1),但是要保存一个附加数组,称之为Used(用过的)数组。当一个随机数Ran最初被放入数组A的时候,置Used[Ran]=1。这就是说,当一个随机数填入A[i]时可以进一步测试是否该随机数已经被使用,而不是像第一个算法那样(可能)进行i步测试。 填写该数组使得A[i]=i+1。然后: for (i = 1; i < N; i++) { Swap(&A[i], &A[RandInt(0, i)]); } a. 证明这三个算法都生成合法的置换,并且所有的置换都是等可能的。 b. 对每一个算法给出你能够得到的尽可能准确的期望的运行时间分析。 c. 分别写出程序来执行每个算法10次,得出一个好的平均值。对于N=250, 500, 1000, 2000运行程序1;对于N=2500,5000

数据结构和算法 链表

随声附和 提交于 2019-12-09 19:38:17
一、单向循环链表 1、链表是一种数据结构,链表的基本组成单元是节点(Node)。节点(Node)包含了:节点数据(val/element)、后一个节点的引用(next)、前一个节点的引用(pre) 2、链表在内存中存储空间是不连续的,每一个节点都包含后一个节点的引用(next)和前一个节点的引用(pre),通过next和pre可以获取在不连续空间存储的节点 3、时间复杂度分析:一、添加和删除的操作:链表的时间复杂度则变成了O(1);二、遍历查找需要的数据::链表的时间复杂度则变成了O(n) 4、链表还是很多算法中有运用,哈希表就是基于链表来解决哈希冲突 5、链表实现:初始化(__init__)、元素的插入和删除(add、append、insert、remove)、链表的遍历(travel)、获取链表长度(length)、元素的查询(search)、链表的逆序、判断链表是否有环(链表是否有环:链表不存在一个结点的next指针是 null-hash表set.add(head)存储节点的引用和快慢指针) 6、while判断,head是否为none,适用于head=head.next;head.next是否为none,适于与head=head.next.next 7、以下python实现代码中 def insert(self, pos, item) 插入链表使用 数字索引 表示位置

数据结构与算法——常用数据结构及其Java实现

懵懂的女人 提交于 2019-12-09 18:27:30
本文采用Java语言来进行描述,帮大家好好梳理一下,在工作和面试中用的上数据结构与算法。亦即总结常见的的数据结构,以及在Java中相应的实现方法,务求理论与实践一步总结到位。 常用数据结构 数组 数组是相同数据类型的元素按一定顺序排列的集合,是一块连续的内存空间。数组的优点是:get和set操作时间上都是O(1)的;缺点是:add和remove操作时间上都是O(N)的。 Java中,Array就是数组,此外,ArrayList使用了数组Array作为其实现基础,它和一般的Array相比,最大的好处是,我们在添加元素时不必考虑越界,元素超出数组容量时,它会自动扩张保证容量。 Vector和ArrayList相比,主要差别就在于多了一个线程安全性,但是效率比较低下。如今java.util.concurrent包提供了许多线程安全的集合类(比如 LinkedBlockingQueue),所以不必再使用Vector了。 链表 链表是一种非连续、非顺序的结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,链表由一系列结点组成。链表的优点是:add和remove操作时间上都是O(1)的;缺点是:get和set操作时间上都是O(N)的,而且需要额外的空间存储指向其他数据地址的项。 查找操作对于未排序的数组和链表时间上都是O(N)。 Java中,LinkedList 使用链表作为其基础实现。

简述数据结构

浪子不回头ぞ 提交于 2019-12-09 15:41:47
数据结构分类 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所示: 每一种数据结构都有着独特的数据存储方式,下面为大家介绍它们的结构和优缺点。 1、数组 数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进行访问,数组下标从0开始。例如下面这段代码就是将数组的第一个元素赋值为 1。 int[] data = new int[100];data[0] = 1; 优点: 1、按照索引查询元素速度快 2、按照索引遍历数组方便 缺点: 1、数组的大小固定后就无法扩容了 2、数组只能存储一种类型的数据 3、添加,删除的操作慢,因为要移动其他的元素。 适用场景: 频繁查询,对存储空间要求不大,很少增加和删除的情况。 2、栈 栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出,从栈顶放入元素的操作叫入栈,取出元素叫出栈。 栈的结构就像一个集装箱,越先放进去的东西越晚才能拿出来,所以,栈常应用于实现递归功能方面的场景,例如斐波那契数列。 3、队列 队列与栈一样,也是一种线性表,不同的是,队列可以在一端添加元素,在另一端取出元素,也就是:先进先出。从一端放入元素的操作称为入队

20182324 2019-2020-1 《数据结构与面向对象程序设计》实验9报告

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-08 22:22:27
20182324 2019-2020-1 《数据结构与面向对象程序设计》实验9报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 殷宇豪 学号: 20182324 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 1.初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数) 2.图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历) 3.完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环 4.完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出 5.完成有向图的单源最短路径求解(迪杰斯特拉算法) 2. 实验过程及结果 (1)根据屏幕提示初始化无向图和有向图 (2)完成有向图和无向图的遍历 (3)图的拓扑排序 (4)无向图的最小生成树 (5)图的单源最短路径求解 3. 实验过程中遇到的问题和解决过程 问题1:对 Java 中 Iterator 的理解 问题1解决方案: java.util.Iterator 在 JDK 帮助文档中这样阐述:public interface Iterator<E> 对 collection 进行迭代的迭代器。迭代器取代了 Java

数据结构与算法习题---最小栈

落花浮王杯 提交于 2019-12-08 21:26:27
最小栈 支持push、pop、top操作。 支持getMin操作,以O(1)的时间复杂度获取栈中最小值。 方法一、双栈 思路:一个栈存放正常数据,另一个栈存放 (历代) 最小值。push时判断新加入的元素和最小栈的栈顶元素的大小,若新加入的元素更小,则不仅要压入正常栈,还要压入最小栈;否则仅压入正常栈即可。pop的时候。也要判断一下,弹出栈的元素是否是之前的最小值,如果是,也要在最小栈中将最小值弹出。 注意:这两个栈可以使用同一个数组。 #include<stdio.h> #include<stdlib.h> #define MAXSIZE 20 typedef int ElemType; typedef struct stack { ElemType data[MAXSIZE]; int top1; int top2; }*MinStack; // 初始化最小栈 MinStack Init() { MinStack ms = (MinStack)malloc(sizeof(struct stack)); if(ms == NULL) return NULL; ms->top1 = -1; ms->top2 = MAXSIZE; return ms; } // Push void Push(MinStack ms, ElemType x) { if(ms == NULL)

20182322 2019-2020-1 《数据结构与面向对象程序设计》实验9报告

故事扮演 提交于 2019-12-08 21:20:35
课程:《程序设计与数据结构》 班级: 1823 姓名: 王美皓 学号:20182322 实验教师:王志强 实验日期:2019年11月25日 必修/选修: 必修 1.实验内容 完成图的综合实践 (1)初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数) (2)图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历) (3)完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环 (4)完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出 (5)完成有向图的单源最短路径求解(迪杰斯特拉算法) 2. 实验过程及结果 实验一创建图,初始化无向图和有向图 //设置边及它的权值 private class B { int i,w;//设置权值 B nextX; //设置指针 } //设置顶点 private class N { char dingdian; // 设置顶点 B firstX; }; private int Enum; // 边的数量 private N[] mV; // 顶点数组 //创建图 public Sorting(char[] dingdian, EData[] bian) { int lenv =

学号 2019-2020-2314《数据结构与面向对象程序设计》实验九实验报告

自作多情 提交于 2019-12-08 20:55:37
学号 2019-2020-2314《数据结构与面向对象程序设计》实验九实验报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 鞠明翰 学号:20182314 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 完成图的综合实践 (1)初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数) (2)图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历) (3)完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环 (4)完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出 (5)完成有向图的单源最短路径求解(迪杰斯特拉算法) 2. 实验过程 生成图: import java.io.*; public class ToPoTest { public static void main(String[] args) throws IOException { ToPo directedGraph = new ToPo(); try{ directedGraph.topoSort(); }catch(Exception e){ System.out.println("graph has

数据结构与算法之数组

房东的猫 提交于 2019-12-08 15:17:56
本章重点: 1.Java中数组的基础知识; 创建数组: 在许多的编程语言中(甚至有些面向对象语言,如c++),数组也是基本类型,但是在Java中把他们当做对象来对待,因此在创建数组时必须使用new操作符: int[] intArray; intArray = new int[100]; []操作符对于编译器来说是一个标志,它说明正在命名的是数组对象而不是普通的变量。 或: int[] intArray = new int[100]; int intArray[] = new int[100]; 由于数组是一个对象,所以它的名字intArray是数组的一个引用,而不是数组本身。数组存储在内存中的其他地址中,而intArray仅仅保存着这个地址。正如大多数编程语言一样,数组一旦被创建,数组大小便不可改变。 访问数组数据项: 数组数据项通过使用方括号中的下标数来访问: temp = intArray[3]; 注意:无论是在c、c++,还是java中,第一个数据项的下标都是0,所以一个有10个数据项的数组下标是从0到9.强撸会报Array Index Out Of Bounds数组越界错误。 初始化: 当创建整型数组之后,如果不另行指定,那么整型数组会自动初始化为空。与C++不同的是,即使通过方法来定义数组也是这样的。创建一个对象数组如下: autoData[] carArray =