tip:但凡要用遍历处理的二叉树问题,都可以用morris遍历来解决。时间复杂度为N,空间复杂度为1
(装逼神器,面试场提升逼格)
morris的流程:
当前节点,记为cur。
A。如果cur无左孩子,cur 向右移动。
B。如果cur有左孩子,找到左子树上最右的结点,记为 mostright.
(1) 如果mostright的右孩子为NULL,让其指向cur,cur向左移动。
(2)如果mostright指向cur,让其指向NULL,cur向右移动。
先搞左神的代码,自己手撸完再回来贴c++;
public static void morrisIn(Node head) {
if (head == null) {
return;
}
Node cur1 = head;
Node cur2 = null;
while (cur1 != null) {
cur2 = cur1.left;
if (cur2 != null) {
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
}
}
System.out.print(cur1.value + ” “);
cur1 = cur1.right;
}
System.out.println();
}
public static void morrisPre(Node head) {
if (head == null) {
return;
}
Node cur1 = head;
Node cur2 = null;
while (cur1 != null) {
cur2 = cur1.left;
if (cur2 != null) {
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
if (cur2.right == null) {
cur2.right = cur1;
System.out.print(cur1.value + ” “);
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
}
} else {
System.out.print(cur1.value + ” “);
}
cur1 = cur1.right;
}
System.out.println();
}
public static void morrisPos(Node head) {
if (head == null) {
return;
}
Node cur1 = head;
Node cur2 = null;
while (cur1 != null) {
cur2 = cur1.left;
if (cur2 != null) {
while (cur2.right != null && cur2.right != cur1) {
cur2 = cur2.right;
}
if (cur2.right == null) {
cur2.right = cur1;
cur1 = cur1.left;
continue;
} else {
cur2.right = null;
printEdge(cur1.left);
}
}
cur1 = cur1.right;
}
printEdge(head);
System.out.println();
}
二叉搜索树的(查找,删除,插入)(小米面试遇到的题目)
1,删除二叉搜索树的某个结点:(面试的时候这个点没学,当场干懵逼,弱鸡)
先search,查找该结点是否存在,不存在不用删除。
如果存在该结点,删除掉该结点,把该结点的直接前驱结点,或者后继结点放在该位置。
即,左子树最右的结点,或者右子树最左面的结点。
2,查找,时间复杂度为logN.
3,插入,时间复杂度为logN.
(哈希表直接地址方法,查找时间复杂度1。然而,map(红黑树),时间复杂度为logN ,map的key(红黑树),是基于比较的方便查找某个刚刚大于某个数的数,时间复杂度依然为logN,哈希表为N)(哈希表的增删改查都是1)
A,AVL树(平衡性高度严格的二叉平衡搜索树(每个结点的左右子树,高度差小于等于1)),
B,红黑树(具有某种平衡性的搜索二叉树)
1)根节点和叶节点全部是黑
2)相邻结点不能为红
3)任意一个结点的两个链,黑色结点的差值不大于1,(长链不超过短链的2倍)
维持平衡性有左旋转(逆时针旋转),右旋(顺时针旋转)。