1.Morris遍历
morris:
开始时,cur来到头结点位置
(1)如果cur没有左孩子,cur向右移动(cur=cur.right);
(2)如果cur有左孩子,找到左子树上最右的节点mostRight:
a. 若mostRight的右指针指向空,让其指向cur,然后cur向左移动(cur=cur.left);
b. 若mostRight的右指针指向cur,让其指向null,然后cur向右移动(cur=cur.right);
(3)cur为空时遍历停止;
public static class Node {
public int value;
Node left;
Node right;
public Node(int data) {
this.value = data;
}
}
public static void morris(Node head){
if(head==null){
return;
}
Node cur=head;
Node mostRight=null;
while(cur!=null){//过流程
mostRight=cur.left; //mostRight是cur的左孩子
if(mostRight!=null){//有左子树
while(mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
//mostRight变成了cur左子树上,最右的节点
if(mostRight.right==null){//第一次到达cur
mostRight.right=cur;
System.out.println(cur.value+" ");
cur=cur.left;
continue;
}else{//mostRight.right==cur
System.out.println(cur.value+" ");
mostRight.right=null;
cur=cur.right;
}
}else {
System.out.println(cur.value+" ");
cur=cur.right;
}
}
}
morris改先序:
经过一次:直接打印
经过两次:第一次打印
public static void morrisPre(Node head){
if(head==null){
return;
}
Node cur=head;
Node mostRight=null;
while(cur!=null){
mostRight=cur.left;
if(mostRight!=null){
while(mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
if(mostRight.right==null){
mostRight.right=cur;
System.out.println(cur.value+" ");
cur=cur.left;
continue;
}else{
// System.out.println(cur.value+" ");跟原本的遍历只这一步不同
mostRight.right=null;
cur=cur.right;
}
}else {
System.out.println(cur.value+" ");
cur=cur.right;
}
}
}
morris改中序:
经过一次:直接打印
经过两次:第二次打印
public static void morrisIn(Node head) {
if(head==null){
return;
}
Node cur=head;
Node mostRight=null;
while(cur!=null){
mostRight=cur.left;
if(mostRight!=null){
while(mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
if(mostRight.right==null){
mostRight.right=cur;
cur=cur.left;
continue;
}else{
System.out.println(cur.value+" ");
mostRight.right=null;
cur=cur.right;
}
}else {
System.out.println(cur.value+" ");
cur=cur.right;
}
}
}
morris改后序:
经过一次:直接打印
经过两次:第二次到:逆序打印左子树右边界
最后逆序打印整棵树右边界
public static void morrisPos(Node head) {
if(head==null){
return;
}
Node cur=head;
Node mostRight=null;
while(cur!=null){
mostRight=cur.left;
if(mostRight!=null){
while(mostRight.right!=null&&mostRight.right!=cur){
mostRight=mostRight.right;
}
if(mostRight.right==null){
mostRight.right=cur;
cur=cur.left;
continue;
}else{
mostRight.right=null;
printEdge(cur.left);
cur=cur.right;
}
}else {
cur=cur.right;
}
}
printEdge(head);
}
public static void printEdge(Node head) {
Node tail = reverseEdge(head);
while(tail!=null){
System.out.println(tail.value+" ");
tail=tail.right;
}
reverseEdge(tail);
}
public static Node reverseEdge(Node from) {
Node pre=null;
while(from!=null){
Node next=from.right;
from.right=pre;
pre=from;
from=next;
}
return pre;
}
2.二叉树节点间的最大宽度
(1)经过头:左height+1+右height
(2)不经过头:左子树maxDistance与右子树maxDistance中较大的
public static class ReturnType{
public int maxDistance;
public int h;
public ReturnType(int maxDistance,int h){
this.maxDistance=maxDistance;
this.h=h;
}
}
public static ReturnType process(Node head) {
if(head==null){
return new ReturnType(0,0);
}
ReturnType processLeft = process(head.left);
ReturnType processRight = process(head.right);
int includeHead=processLeft.h+processRight.h+1;
int max = Math.max(Math.max(processLeft.maxDistance, processRight.maxDistance), includeHead);
int height=Math.max(processLeft.h,processRight.h)+1;
return new ReturnType(max,height);
}
3.派对员工最大快乐值
(1)头来:直接下属不来的最大快乐值加上自己的
(2)头不来:直接下属可以选择来或不来的最大快乐值
public static class Employee{
public int happy;
public List<Employee> nexts;
}
public int getMaxHappy(Employee boss){
Info info = process(boss);
return Math.max(info.buMaxHappy,info.laiMaxHappy);
}
public static class Info{
public int buMaxHappy;
public int laiMaxHappy;
public Info(int lai,int bu){
this.laiMaxHappy=lai;
this.buMaxHappy=bu;
}
}
public Info process(Employee x){
if(x.nexts.isEmpty()){//x是基层员工的时候
return new Info(x.happy,0);
}
int lai=x.happy;//x来的情况下,整棵树的最大收益
int bu=0;//x不来的情况下,整棵树的最大收益
for (Employee next : x.nexts) {
Info info = process(next);
lai+=info.buMaxHappy; //注意这里只能加不来的happy
bu+=Math.max(info.buMaxHappy,info.laiMaxHappy);
}
return new Info(lai,bu);
}