二叉树浅谈
二叉树二叉树:在二叉树中,任意节点的度<=2
二叉树分类:
二叉查找树
平衡二叉树
红黑树
二叉查找树
每一个节点上最多有两个子节点
任意节点左子树上的值都小于当前节点
任意节点右子树上的值都大于当前节点
小的存左边,大的存右边,一样的不存
遍历方式:
前序遍历:当前节点,左子节点,右子节点
中序遍历:左子节点,当前节点,右子节点
后序遍历:左子节点,右子节点,当前节点
层序遍历:一层一层地去遍历
平衡二叉树任意节点左右字数高度差不超过1
旋转机制
左左 -> 右旋
左右 -> 局部左旋再右旋
右右 -> 左旋
右左 -> 局部右旋再左旋
红黑树添加节点的规则:
每一个节点是红色或黑色
根节点必须是黑色
叶节点(Nil)是黑色
两个红色节点不能相连
任意节点到所有后代叶节点的简单路径上,黑色节点数量相同
节点添加规律:
默认添加的节点是红色的
根
直接变成黑色
非根
父黑
不需要任何操作
父红
叔叔红
将父节点设置为黑,叔叔节点设置为黑
祖父节点设置为红
如果祖父节点是根,再变回红
如果祖父节点非根,再将祖父节点设 ...
java单列集合学习
List接口的实现类
ArrayList:动态数组实现,允许重复元素
LinkedList:双向链表实现,允许重复元素
Set接口的实现类
HashSet:基于哈希表实现,不允许重复元素
LinkedHashSet:基于哈希表和链表实现,不允许重复元素,保持插入顺序
TreeSet:基于红黑树实现,不允许重复元素,元素自动排序
CollectionCollection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的
collection方法
把给定的对象添加到当前集合中
1. 如果我们向List系列集合中添加数据,那么方法永远会返回true,因为List系列是允许元素重复
2.如果我们向Set系列集合中添加数据,那么方法会根据是否存在而返回true或false,因为Set系列是不允许元素重复的
12Collection<E> coll = new ArrayList<> ();coll.add(e);
清空集合中所有的元素
123Collection<E> coll = new ArrayList<> () ...
java中泛型浅淡
[[java]]Java中的泛型(Generics)是一种支持泛型编程的工具,它允许程序员在编译时提供类型信息,从而提高代码的复用性和安全性。泛型的应用统一了数据类型,把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,应为在编译阶段类型就能确定下来。
泛型中的细节
泛型中不能写基本数据类型(int,float,double,boolean,byte,char,short,long)
指定泛型的具体类型后,传递数据时,可以传入该类型和他的子类类型
如果不写泛型,类型默认是Object
泛型的种类
泛型类:
允许你定义一个类,该类可以操作任意类型的数据,而不需要在代码中使用具体的类型
123456789public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; }}
泛型接口:
允许你定义一个接口,该接口可以操作任意类型的数据
123public in ...
区间合并
区间合并12345678910111213141516171819private static int[][] merge(int[][] a) { if (a == null || a.length == 0 || a[0].length == 0) { return new int[0][2]; } Arrays.sort(a, Comparator.comparingInt(item -> item[0])); List<int[]> res = new ArrayList<>(); for (int[] arr : a) { int left = arr[0]; int right = arr[1]; if (res.size() == 0 || res.get(res.size() - 1)[1] < left) { res.add(new int[]{left, r ...
离散化
离散化123456789101112131415161718// 去重 + 排序 List<Integer> distinctSorterAlls = alls.stream().distinct().sorted().collect(Collectors.toList()); // 离散化映射,把离散化的下标映射到连续的数组下标 + 1for (int[] item : add) { int index = Collections.binarySearch(distinctSorterAlls, item[0]) + 1; a[index] += item[1]; } // 前缀和 for (int i = 0; i < distinctSorterAlls.size(); i++) { s[i + 1] = s[i] + a[i]; } // 离散化映射,把离散化的下标映射到连续的数组下标 + 1for (int[] item : query) { int l = Co ...
位运算
位运算12345eg: n的二进制表示中第k位是几1. 先把第k位移到最后一位 n>>k2. 看个位是几 x&11 + 2 => 求n的第k位数字: n >> k & 1
返回n的最后一位:lowbit(n) = n & -n
双指针算法
双指针算法123456789for (int i = 0, j = 0; i < n; i ++ ){ while (j < i && check(i, j)) j ++ ; // 具体问题的逻辑}常见问题分类: (1) 对于一个序列,用两个指针维护一段区间 (2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
抓包初体验
Wireshark过滤规则按ip地址过滤想看源ip为xx的包过滤条件中输入:ip.src==源ip地址
自己电脑的ip地址查询:ipconfig /all
想看目标ip为xx的包过滤条件中输入:ip.dst==目标ip地址
想看源或目标ip为xx的包过滤条件中输入:ip.addr==ip地址
按MAC地址过滤想看源MAC为xx的包过滤条件中输入:eth.src==源MAC地址
自己电脑的MAC地址查询:ipconfig /all
想看目标MAC为XX的包过滤条件中输入:eth.dst==目标MAC地址
想看源或目标MAC为xx的包过滤条件中输入:eth.addr==MAC地址
按端口号过滤端口号:表示一台计算机中的特定进程所提供的服务,用来区分相同计算机所提供的不同服务
按照端口号分类:
公认端口:0~1023。它们紧密绑定于一些服务,通常这些端口的通讯明确表明了某种服务的协议,如:80端口对应与HTTP通信,21端口绑定与FTP服务,22端口绑定与ssh服务,25端口绑定于SMTP服务,135端口绑定与RPC(远程过程调用)服务。
注册端口:1024~49151。它们松散的绑定于一 ...
前缀和
前缀和一维前缀和123456789S[0] = 0S[i] = a[0] + a[1] + a[2] + ... + a[i - 1]S[i + 1] = S[i] + a[i]a[l] + ... + a[r] = S[r + 1] - S[l]//原地前缀和for (int i = 1; i < length; i++) { nums[i] += nums[i - 1];}
二维前缀和1234S[i, j] = 二维数组a[i,j]第i行j列格子左上部分所有元素的和S[i, j] = S[i - 1, j] + S[i, j - 1] - S[i - 1, j - 1] + a[i, j]以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和为:S[x2, y2] - S[x1 - 1, y2] - S[x2, y1 - 1] + S[x1 - 1, y1 - 1]
差分一维差分1给区间[l, r]中的每个数加上c:B[l] += c, B[r + 1] -= c
二维差分12给以(x1, y1)为左上角,(x2, y2)为右下角的子 ...