int数据。右移16位,只保留前面的16位,用来参与运算。
0.登录后自动跳转到目标页面。
需求例子:跳转到直播页,首先跳转到登录页面,登录成功后再自动跳转到直播页面。
比较好的方案:随着业务逻辑越来越复杂,不需要刻意去修改原来的代码。
1.1 拦截:传参数+type,登录成功后,再根据type跳转。
1.2 传一个intent过去,
1.3 借助路由ARoute,DRoute. 通过路由转发。
1.4 通过APT,(Activity启动流程拦截,是否需要登录),
需要对源码熟悉,还要适配不同Android版本。复杂,可控性不强。侵入性大。
BaseActivity 。 复写startActivityForResult。
1.5 其他更有方案?
每个地方都判断是否登录,就太麻烦。
Intent intent = new Intent(this, LiveActivity.class);
if(login){ // 有没有登录
Intent loginIntent = new Intent(this, LoginActivity.class);
loginIntent.putExtra("targetIntent", intent);
startActivity(loginIntent);
} else {
}
public class BaseActivity extends AppCompatActivity {
// 所有需要登录的页面。
private static List<String> mNeedLoginClassNames = new ArrayList<>();
static {
mNeedLoginClassNames.add(LiveActivity.class.getName());
//...
}
@Override
public void startActivityForResult(Intent intent, int requestCode) {
String className = intent.getComponent().getClassName();
// 判断是否需要登录。
if(mNeedLoginClassNames.contains(className)){
Intent loginIntent = new Intent(this, LoginActivity.class);
loginIntent.putExtra("target", intent); // 传入目标intent
super.startActivityForResult(loginIntent, requestCode);
return;
}
// TODO: 进入登录页面,由于传递过去了target,登录后,再跳目标Activity。
super.startActivityForResult(intent, requestCode);
}
}
41. 树和二叉树。
1.树的定义和分类。
- 1.1 有且只有一个根节点;
- 1.2 有若干个互不相交的子树,这些子树本身也是一棵树(重要思想:算法求解 大部分可以采用递归);
把大问题分成若干小问题,小问题的解决方式都是一致的。 - 1.3 二叉树的考点,优先考虑递归。
1.1 重要的名词
双亲节点(父节点),子节点,节点, 兄弟节点(有共同的父节点),
度:有多少个子节点,就是多少度。
深度:
叶子节点:没有子节点的节点。
1.2 树的分类
- 一般树:
任意一个节点的子节点,都不受限制。 -
二叉树(AVL树,红黑树,堆排序,优先级队列)- 重点内容。
任意一个节点的子节点的个数,必须小于3. 且子节点位置不能更改(左右子节点)。 - 森林
n个互不想叫树的集合。
2.树的存储
链式存储、顺序存储.
如何将一棵树存起来?
eg: 根节点 A 有B,C,D 三个子元素。
B有EF;C有GH2个子元素。
2.1 双亲表示法
存双亲的角标。找父亲比较简单,但是找孩子比较麻烦。
角标 |元素|父节点角标
0 |A |-1
1 |B |0
2 |C |0
3 |D |0
4 |E |1
5 |F |1
6 |G |2
7 |H |2
2.2 孩子表示法,比较耗内存。
找自孩子比较简单,但是找父亲节点麻烦(需要遍历整个链表)。
角标 |元素|孩子的角标
0 | A |1|2|3
1 |B |4|5|^
2 |C |6|7|^
3 |D |||^
4 |E |||^
5 |F |||^
6 |G |||^
7 |H |||^
链表的方式:比上面节省内存。
角标 |元素|孩子的角标
0 |A |1->2->3->null
1 |B |4->5->null
2 |C |6->7->null
3 |D |->null
4 |E |->null
5 |F |->null
6 |G |->null
7 |H |->null
2.3 孩子双亲表示法。找父亲和孩子都比较简单。
角标 |元素|父亲|孩子的角标
0 |A |-1 |1->2->3->null
1 |B |0 |4->5->null
2 |C |0 |6->7->null
3 |D |0 |->null
4 |E |1 |->null
5 |F |1 |->null
6 |G |2 |->null
7 |H |2 |->null
以上三种,找兄弟节点都比较麻烦。
2.4 二叉树表示法,将二叉树存起来。
#include <iostream>
#define TREE_SIZE 100
typedef char Element;
typedef struct CTNode {
int child; // 孩子的下标
struct CTNode* next;
} * CTNodePtr;
typedef struct {
Element data; // A,B,C
int parent; // 双亲节点的角标
CTNodePtr firstChild; // 第一个子孩子的CTNode*
} CTree;
typedef struct {
CTree nodes[TREE_SIZE]; // 节点集合的数组
int root; // 根节点的位置
int size; // 节点的个数
} Tree;
void main() {
Tree tree ;
tree.root = 0;
tree[0] = CTree();
}
3.树、森林与二叉树之间的转换。
eg:A有 BCD子节点;
B有EF节点;D有G节点。
1.如果有左子节点,当坐其左节点;
2.左节点,把兄弟节点,当做右节点。
转换后:一棵树转换成二叉树之后,并没有右孩子。
A有左节点,B;
B有左节点E,右节点C;
E有右节点F,C有右节点D,D有左节点G。
另外一种转换方法:
1.把兄弟节点用线连起来
2.只保留第一个左孩子之间的连线。
3.删除双亲与非第一个孩子的连线,整理保留的连线。摆放成二叉树结构,转换完成。
如何转回来(二叉树转树),
1.加线条(若某节点的左孩子存在,则将这个左孩子的右孩子节点,右孩子节点....)。都作为该节点的孩子用线连接起来。
2.去线:删除原二叉树中所有节点与其 右边孩子的连线。
3.再做调整。
森林转二叉树。
A树有IBC。
D树有EF;
G树无子节点:
转成二叉树后:
A有ID两个节点;
I有右节点B,B有右节点C;
D有左节点E,E有右节点F;D有右节点G。
1.每一棵树,都需要转成二叉树。
2.把边上的树,当做右节点连接起来,
3.完成森林转二叉树。
TODO:二叉树 怎么转回成森林?
TODO:
二叉树遍历(前、中,后序),递归/非递归
二叉树的序列化和反序列化;
二叉树的常用算法;
二叉树的基本概念和分类。










网友评论