一、演算法介紹
morris演算法充分利用了二叉樹葉子節點下的空間,從而可以在時間複雜度為o(n),空間複雜度為o(1)的條件下,前中後序遍歷二叉樹(不是完全二叉樹也可以使用)。
而常見的遍歷二叉樹的方法為遞迴和棧迭代,這兩種方法的時間複雜度雖然也為o(n),但是空間複雜度需要o(n),因此morris演算法可以極大節省空間。
二、演算法原理
首先來到當前節點記為cur。
1.如果cur無左孩子,cur向右移動。
2.如果cur有左孩子,那麼找到cur左子樹的最右的節點,記為mostright。
2.1如果mostright的right指標指向空,則讓其指向cur,然後cur向左移動
2.2如果mostright的right指標指向cur,讓其指回空,然後cur向右移動。
三、演算法實現
1.前序遍歷
1public
static
void
morrispre(node head)
5 node cur =head;
6 node mostright = null;7
while (cur != null
) 13
if (mostright.right == null) else
21 } else
24 cur = cur.right;//
右移25}26
system.out.println();
27 }
2.中序遍歷
1public
static
void
morrisin(node head)
5 node cur = head; //
當前節點
6 node mostright = null; //
左子樹的最右節點
7while(cur!=null)13
if(mostright.right==null)else20}
21 system.out.print(cur.value+" ");
22 cur =cur.right;23}
24system.out.println();
25 }
3.後序遍歷
前序遍歷和中序遍歷本質上並沒有太大的區別,但morris的後序遍歷有較大的改動。
由於遞迴等版本的遍歷二叉樹後序遍歷是在第三次到達節點的時候列印本次節點,但是morris遍歷只能到達乙個節點兩次。
因此可以採用到達該節點第二次的時候列印該節點左子樹的逆序右邊界的方法來列印後序遍歷。
例如有一顆二叉樹 4
2 6
1 3 5 7
其中右邊界分別為1 , 3 2 , 5 , 7 6 4
其中要用到
反轉鍊錶
1public
static
node reverseedge(node from)
10return
pre;
11 }
列印邊界函式
1public
static
void
printedge(node head)
8reverseedge(tail);
9 }
後序遍歷函式
1public
static
void
morrispos(node head)
5 node cur =head;
6 node mostright = null;7
while(cur!=null)13
if(mostright.right==null)else21}
22 cur =cur.right;23}
24 printedge(head);//
最後再單獨列印最右邊界
25system.out.println();
26 }
Morris演算法遍歷二叉樹
中序遍歷 演算法步驟 1 如果當前節點的左子節點為空,則輸出當前節點,並將當前節點置為該節點的右子節點。2如果當前節點的左子節點不為空時,則找到當前節點左子樹的最右節點 該節點為當前節點中序遍歷的前驅節點 a 如果最右節點的右指標為空,則將最右節點的右指標指向當前節點,並把當前節點置為其左子節點。b...
二叉樹遍歷演算法 Morris演算法
morris演算法的時間複雜度是o n 空間複雜度為o 1 基本思想是 1.找到當前節點的前驅節點,即左節點的最右節點,若為空則指向當前節點,若為當前節點則表明該節點左邊以及該節點已經遍歷完,並將前驅節點的有指標恢復為空 2.若當前節點的左節點為空,則直接訪問當前節點右節點 前序遍歷和中序遍歷 差不...
Morris遍歷二叉樹
morris遍歷的實質就是避免用棧結構,而是讓下層到上層有指標,具體是通過讓底層節點指向null的空閒指標指回上層的某個節點,從而完成下層到上層的移動。中序遍歷的過程如下 1.假設當前子樹的頭節點為h,讓h的左子樹中最右節點的right指標指向h,然後h的左子樹繼續步驟1的處理過程,直到遇到某乙個節...