遍历

二叉树相关基本问题

微笑、不失礼 提交于 2020-01-17 23:29:16
二叉树相关基本问题 实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式 在二叉树中找到一个节点的后继节点 二叉树的序列化和反序列化 二叉树按层序列化 判断一颗二叉树是否是平衡二叉树? 判断一棵树是否为搜索二叉树?判断一棵树是否是完全二叉树? 已知一颗完全二叉树,求其节点的个数? (from 左神算法初级班第五节) 1.实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式 1) 递归方式 实现先序、中序、后序遍历 打印时机不同,实现不同的顺序遍历 先序遍历:打印第一次访问的节点 中序遍历:打印第二次访问的节点 后序遍历:打印第三次访问的节点 代码: public static class Node { public int value ; public Node left ; public Node right ; public Node ( int data ) { this . value = data ; } } public static void preOrderRecur ( Node head ) { //先序遍历 if ( head == null ) { return ; } System . out . print ( head . value + " " ) ; preOrderRecur ( head . left ) ;

# [洛谷3376] 网络最大流模板题

不羁的心 提交于 2020-01-17 22:25:58
[洛谷3376] 网络最大流模板题 洛谷3376 题意 网络最大流模板题,题意很直白。 给出源点,汇点,点个数,边条数,以及每条边的流量,求源点到汇点的最大流量。 思路 Dinic算法简介 最大流经典算法Dinic算法,理论复杂度 \(O(n^2m)\) ,但是实际运用中远远达不到这个上界,可以说是比较容易实现的效率最高的网络流算法之一,一般能处理 \(10^4 -10^5\) 规模的网络,特别的地,Dinic算法求解二分图最大匹配的理论时间复杂度为 \(O(m\sqrt{n})\) ,实际表现则更快。 实现步骤 在残量网络(剩余流量大于0的子图)上BFS求出节点的层次,构造分层图 在分层图上DFS寻找增广路,在回溯时实时更新剩余流量,每个点可以流向多条边。 优化技巧 当前弧优化 一个点可能有多条出边,在DFS寻找增广路的时候,如果遍历该点的出边时,发现有些边已经没有剩余流量时,记录下当前遍历的点,下次再碰到该点时,无需从头开始遍历,直接从记录的位置开始遍历(因为记录位置之前的出边都没有剩余流量了,没有遍历的必要,代码实现:边使用链式前向星存储,使用额外数组cur[]复制head[]的值,实现cur代替head进行遍历,并及时更新cur的值,也就是修改头结点的指向)。 多路增广优化 爆点优化 当DFS遍历时发现一个点没有了流出的流量,则把该点的deep值置为-2,将无用的点抛弃

迭代器和生成器

[亡魂溺海] 提交于 2020-01-17 07:57:50
迭代器(iter) 什么是迭代器 迭代器作为容器,可以保存多个数据,迭代器是一个可以记住遍历的位置的对象,当遍历迭代对象 的时候,下一次的获取到的值会接着上次遍历的位置,直到所有的元素被访问完,那么该迭代对象变成空。迭代器只能依次往后遍历,不能逆向操作。 迭代器的两个基本的方法: iter():将序列转化为迭代器对象 next():依次遍历迭代器中的元素 获取迭代器中的元素 不管用那种方式去获取了元素的值,那么这个元素在迭代器中就不存在了 1)获取单个元素:next(迭代器) / 迭代器. next () -> 获取迭代器中的第一个元素 2)遍历: for 变量 in 迭代器: pass iter1 = 'hello' print ( iter1 ) # <str_iterator at 0x1d529ebbe08> print ( type ( iter1 ) ) # str_iterator print ( next ( iter1 ) ) print ( next ( iter1 ) ) print ( next ( iter1 ) ) print ( iter1 . __next__ ( ) ) print ( iter1 . __next__ ( ) ) # StopIteration如果迭代器为空用next获取元素的时候会报错 或者 for item in iter1

java中enum类型的使用

僤鯓⒐⒋嵵緔 提交于 2020-01-17 05:06:52
java 枚举类型enum 的使用 最近跟同事讨论问题的时候,突然同事提到我们为什么java 中定义的常量值不采用enmu 枚举类型,而采用public final static 类型来定义呢?以前我们都是采用这种方式定义的,很少采用enum 定义,所以也都没有注意过,面对突入起来的问题,还真有点不太清楚为什么有这样的定义。既然不明白就抽时间研究下吧。 Java 中的枚举类型采用关键字enum 来定义,从jdk1.5才有的新类型,所有的枚举类型都是继承自Enum 类型。要了解枚举类型,建议大家先打开jdk 中的Enum 类简单读一下,这个类里面定义了很多protected 方法,比如构造函数,如果要使用这些方法我们可以把枚举类型定义到当前类中。每个枚举类型,都有自己的名字和顺序,当我们输出一个枚举类型的时候,会输入枚举类型的name ,具体可以参考下面的例子。 一、 通常定义常量方法 我们通常利用public final static 方法定义的代码如下,分别用1 表示红灯,3 表示绿灯,2 表示黄灯。 package com.csdn.myEnum; public class Light { /* 红灯 */ public final static int RED =1; /* 绿灯 */ public final static int GREEN =3; /* 黄灯 */

Java集合一

泄露秘密 提交于 2020-01-17 03:38:49
java的集合类主要由两个接口派生而出:Collection && Map 这两个接口是集合框架的根接口     Collection----直接派生:Set(无序集合,元素不可重复) List(有序集合,元素可以重复) Queue队列          Map实现类用于保存具有映射关系的数据(每项数据都是key-value对)key用于标识集合里的每项数据     可以把java集合分为3大类:Set集合类似于一个罐子,把对象添加到Set集合时,Set集合无法记住元素添加的顺序                  List类似数组,长度可变,可以元素重复,有序集合                 Map也类似罐子,只是每个数据都是由key-value组成 Collection接口提供的方法:     boolean add(Object o):向集合里添加一个元素     boolean addAll(Collection c):将集合c里的元素添加的指定集合中     void clear():清除集合里所有的元素,将集合长度变为0     .。。。。。参考Api文档 使用Lambda表达式遍历集合     Iterable接口新增了forEach(Consumer action)默认方法,这个接口是Collection接口的父接口,Collection集合可以直接调用该方法

DFS及有向图的拓扑排序

痴心易碎 提交于 2020-01-16 14:59:50
一个有向图的DFS森林可能具有的全部类型的边: 树向边、回边、从顶点到树中非子女子孙的前向边、交叉边。所有不属于前三种类型的边都属于交叉边。 一条回边的存在意味着有向图具有一个有向的回路。如果一个有向图的DFS森林没有回边,该有向图是一个无环有向图,即有向无环图的简称。 拓扑排序: 按某种次序列出有向图中的顶点,使得对于图中每一条边来说,边的起始顶点总是排在边的结束顶点之前。这个问题称为拜年排序。 拓扑排序的两个算法: 1,DFS。 执行一次DFS遍历,并记住顶点变成死端(即退出遍历栈)的顺序。将该顺序反过来就得到了拓扑排序的一个解。当然,在遍历的时候不能遇到回边。如果遇到一条回边,该图就不是无环有向图,并且对它顶点的拓扑排序是不可能的。 2,基于减治法: 不断地做这样的一件事,在余下的有向图中求出一个源,它是一个没有输入边的顶点,然后把它和所有从它出发的边都删除。如果有多个这样的源,可以任意选择一个。如果这样的源不存在,算法停止,因为该问题是无解的。 来源: https://www.cnblogs.com/cmleung/archive/2011/04/26/2028872.html

AcWing 907 区间覆盖

时光总嘲笑我的痴心妄想 提交于 2020-01-16 14:14:08
题目描述: 给定N个闭区间[ai,bi]以及一个线段区间[s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。 输出最少区间数,如果无法完全覆盖则输出-1。 输入格式 第一行包含两个整数s和t,表示给定线段区间的两个端点。 第二行包含整数N,表示给定区间数。接下来N行,每行包含两个整数ai,bi,表示一个区间的两个端点。 输出格式 输出一个整数,表示所需最少区间数。 如果无解,则输出-1。 数据范围 1≤N≤10^5, −10^9≤ai≤bi≤10^9, −10^9≤s≤t≤10^9 输入样例: 1 5 3 -1 3 2 4 3 5 输出样例: 2 分析: 我们先对区间按左端点从小到大排序,然后遍历区间。在所有左端点不大于s的区间中选择右端点最大的那个区间,设选择的区间为[l1,r1],则[s,r1]已经被覆盖了,更新需要被覆盖区间的起点s = r1,继续遍历区间,再次找到所有左端点不大于s的区间中右端点最大的区间,重复该过程直至更新后的s超过了终点t。由于每次选择的都是所有合法区间中能够覆盖[s,t]中尚未被覆盖区间最长的区间,所以显然最后选择的区间数是最少的。 我们在遍历区间的过程中,只有遍历到了左端点超过s的区间才知道之前小于s的区间已经遍历完了,此时才能更新s,并且需要将指针回退一格以便循环继续。几种不能覆盖给定区间的情况是:其一

listdir-isdir-isfile用法解释

梦想与她 提交于 2020-01-16 10:03:58
listdir-isdir-isfile用法解释 此三项用法,都要import os先获取 os.listdir(path)方法,此方法返回一个列表,其中包含有path路径下的目录和文件的名称 注意,这里返回的只是一个某个路径下的文件和子目录的名称,不包括.和…文件 os.path.isdir(filename)和os.path.isfile(filename) 为判别filename是否为文件isfile还是子目录isdir 需要注意的是:filename 为包括绝对路径的文件全名 常见错误:直接使用os.listdir(path)的返回值当做os.path.isdir(filename)和os.path.isfile(filename)的filename值,导致无法判断,这也是经常弄混的地方 正确用法:filename需要用python路径拼接os.path.join(path,file)函数,其中path中如果是当前目录,可以用os.getcwd() 获取,file为不带路径的文件名,可用如下的方法遍历获取(实际应用时,去掉#) #递归遍历目录样例文件 #导入oS模块 import os #待遍历的目录路径 path = "e:\办公" #调用walk方法递归遍历path目录 for root , dirs , files in os . walk ( path ) :

java笔记-集合

隐身守侯 提交于 2020-01-16 07:04:27
集合类相关知识 apache 常用工具类的使用 参考:https://juejin.im/post/5b1695595188257d37761e68 SynchronizedList 和 Vector 的区别 相同点 都是线程安全的 底层都是使用数组来实现的 不同点 (主要就是同步块和同步方法的区别) SynchronizedList有很好的扩展和兼容功能。他可以将所有的List的子类转成线程安全的类。 使用SynchronizedList的时候,进行遍历时要手动进行同步处理。 SynchronizedList可以指定锁定的对象。 Enumeration 和 Iterator 区别 //Enumeration 源码 public interface Enumeration < E > { /** * 是否存在元素 */ boolean hasMoreElements ( ) ; /** * 获取下一个元素 */ E nextElement ( ) ; } // Iterator源码 public interface Iterator < E > { /** * 是否存在下一个元素 */ boolean hasNext ( ) ; /** * 获取下一个元素 */ E next ( ) ; /** * 删除元素 */ default void remove ( ) { throw

递归实现树的三种遍历

本秂侑毒 提交于 2020-01-16 04:28:25
递归实现树的三种遍历(先序,中序,后序) 代码实现: public class Demo09 { //先序遍历 public static void preOrder ( int [ ] arr , int i ) { if ( i >= arr . length ) return ; System . out . print ( arr [ i ] + " " ) ; //先输出根节点 preOrder ( arr , i * 2 + 1 ) ; //输出左子树 preOrder ( arr , i * 2 + 2 ) ; //输出右子树 } //中序遍历 public static void inOrder ( int [ ] arr , int i ) { if ( i >= arr . length ) return ; inOrder ( arr , i * 2 + 1 ) ; //递归输出左子树 System . out . print ( arr [ i ] + " " ) ; //输出根节点 inOrder ( arr , i * 2 + 2 ) ; //递归输出右子树 } //后序遍历 public static void postOrder ( int [ ] arr , int i ) { if ( i >= arr . length ) return ;