文章目录
树是一个非常大的课题,光是概念就能弄的人头昏脑胀。 但是如果掌握了,是有点小小的成就感的。
树结构是应用非常广泛的结构,甚至可以说无处不在。
电脑里的文件夹是不是树结构,省市区县镇乡村是不是树结构,菜单是不是树结构,军队是不是树结构,职位是不是树结构。。。太多了,数都数不过来。
但是从数据库或代码的层面实现,里面的东西就太多了。
数据结构-树
树特点:
1、一个节点,即只有根节点,也可以是一棵树;
2、其中任何一个节点与下面所有节点构成的树成为子树;
3、根节点没有父节点,而叶子节点没有子节点;
4、除根节点外,任何节点有且仅有一个父节点;
5、任何节点可以有0~n个字节点。
平衡二叉树
1、树的左右高度差不能超过1;
2、任何往下递归的左子树和右子树,必须符合第一条性质;
3、没有任何节点的空树或只有根节点的树也是平衡二叉树。
二叉查找树
1、在任何递归子树中,左节点一定在右节点之前遍历;
2、前序,中序,后序,仅指根节点在遍历的位置顺序;
AVL树
一种平衡二叉查找树,增加和删除节点后,通过通过旋转重新达到平衡。
红黑树
1、节点只能是红色或者黑色;
2、根节点必须是黑色;
3、所有NIL节点都是黑色;
4、一条路径上不能出现相邻的两个红色节点;
5、在任何递归子树内,根节点到叶子节点的所有路径上包含相同数目的黑色节点。
红黑树和AVL树的比较
黑深度:当前节点到NIL途径的黑色节点个数。
b-树(注 读作b树,不是b减树,没有减号这个概念)
b-树 就是 b树。
B树也翻译为B-树(是一种多路搜索树 并不是二叉的)
1、定义任意非叶子结点最多只有M个儿子;且M>2;
2、根结点的儿子数为[2, M];
3、除根结点以外的非叶子结点的儿子数为[M/2, M];
4、每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
5、非叶子结点的关键字个数=指向儿子的指针个数-1;
6、非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];
7、非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
8、所有叶子结点位于同一层;
b树是二叉树吗?
b树不是二叉树,因为二叉树每个节点最多有两个子节点,但是b树可以有多个子节点。
但是百度文档第一行居然是b树是二叉树。。。(感觉是写错了)
二叉树可以简称读作b树吗?
不能,按照习惯,英文开头大写字母抽出来读是可以的,但是这里不行。
二叉树(binary tree)
平衡树(balance tree) # b树
二叉查找树(binary search tree) # bst
b树表示的是平衡树。
所以二叉树只有两种叫法,二叉树或binary tree。
什么叫自平衡树?
菜单数据库设计
菜单结构主要的就是id,pid,type(菜单类型)。
关键就在怎么拾掇这堆id,pid上。
什么结构便于使用
正常来说,查出的结构一定是个map,完美的展现层级结构。
但是发现没有,map结构虽然全面,但是如果我想要查询某个按钮?
是不是不好查,估计要解map了,太费劲。
易于展现的结构,不一定易于查询。所以这里换个思路,还是map结构,但是以末级节点作为key,上级节点的集合以数组的形式顺序存放。
如:
{
"crm": {
"8888": [
100,
130,
139
],
"9999": [
100,
130,
914
]
}
}
这样用起来就非常方便了。
获取树的方法
方法太多了,百度上代码一堆。
递归调用获取树
实测可用,没看懂这段代码什么意思。 递归不好把控执行流程。
后来加了日志大概明白了,先循环,匹配到id从list中删除,剩余list中以当前id作为pid继续递归。递归完毕后,resultList再统一添加。
public static List<Resource> getTree(List<Resource> resources, Long id) {
if (StrUtils.isEmptyList(resources)) {
return null;
}
List<Resource> list = new ArrayList<>();
List<Resource> listContinue = new ArrayList<>(resources);
for (Resource item : resources) {
if (item.getPid().equals(id)) {
listContinue.remove(item);
item.setChildren(getTree(listContinue, item.getId()));
list.add(item);
}
}
if (CollectionUtils.isEmpty(list)) {
return null;
}else{
return list;
}
}
一个节点是树吗?
可以是树,树可以只有一个节点。
正向树和反向树结合确定调用链
是这样,某个功能在哪些位置被调用,以及有哪些下级功能。
类似于idea的下级及引用。
实际上实现起来并不难,用两棵树就可以实现。
注:这里树比超链接强大多了,例如多个子级,excel就做不到,或者需要多行,即使实现了也不太优雅。