研究生畢業前一日三題:3,morris遍歷,及其平衡搜尋二叉樹
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倍)
維持平衡性有左旋轉(逆時針旋轉),右旋(順時針旋轉)。