1. 程式人生 > >研究生畢業前一日三題:3,morris遍歷,及其平衡搜尋二叉樹

研究生畢業前一日三題: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倍)

維持平衡性有左旋轉(逆時針旋轉),右旋(順時針旋轉)。