007. 二叉樹的遍歷
阿新 • • 發佈:2020-10-29
------------------------------
- 涉及內容:
- 二叉樹的先中後序遍歷
- 遞迴與非遞迴方式 , 虛擬碼實現
- 2020/10/19
- 應瞭解的內容:
- 先中後序遍歷以根節點作為參照點,遍歷順序如下:
- 先序:根左右
- 中序:左根右
- 後序:左右根
- 畫圖最好理解
先序遍歷
------------------------------------------------------------- - 引數說明: - T:根節點 - lchild:左子樹 - rchild:右子樹 ------------------------------------------------------------- 遞迴: void PreOrder(BiTree T) { if(T) { visit(T); PreOrder( T->lchild ) ; PreOrder( T->rchild ) ; } } 非遞迴:需要藉助棧來實現 void PreOrder(BiTree T) { /* 初始化一個棧 p指標指向頭節點 */ InitStack(s); BiTree p = T; // 如果當前節點不空,或者棧不空, while( p || !IsEmpty(s) ) { while( p ) { visit(p); // 訪問節點,訪問次序,根左右 push(s,p); p = p->lchild; } if( !IsEmpty(s) ) { pop(s,p); p = p->rchild; } } }
中序遍歷
------------------------------------------------------------- - 引數說明: - T:根節點 - lchild:左子樹 - rchild:右子樹 ------------------------------------------------------------- 遞迴: void InOrder(BiTree T) { if(T) { InOrder( T->lchild ) ; visit(T); InOrder( T->rchild ) ; } } 非遞迴:需要藉助棧來實現 void InOrder(BiTree T) { /* 初始化一個棧 p指標指向頭節點 */ InitStack(s); BiTree p = T; // 如果當前節點不空,或者棧不空, while( p || !IsEmpty(s) ) { if( p ) { push(s,p); p = p->lchild; } else { pop(s,p); visit(T); // 訪問節點,訪問次序:左根右 p = p->rchild; } } }
後序遍歷
------------------------------------------------------------- - 引數說明: - T:根節點 - lchild:左子樹 - rchild:右子樹 ------------------------------------------------------------- 遞迴: void PostOrder(BiTree T) { if(T) { PostOrder( T->lchild ) ; PostOrder( T->rchild ) ; visit(T); } } 非遞迴:非遞迴後序遍歷的節點要兩次入棧,兩次出棧 struct element{ BiTree *ptr; int flag; // flag表示入棧的次數 }elem; void PostOrder(BiTree T) { /* 初始化一個棧 p指標指向頭節點 */ InitStack(s); BiTree p = T; // 如果當前節點不空,或者棧不空, while( p || !IsEmpty(s) ) { if( p ) { // L1 elem.ptr = p; elem.flag = 1; push(s,elem); // 將指標地址以及入棧次數儲存到棧中 p = p->lchild; } else { elem = push(s,elem); p = elem.ptr; if(elem.flag == 1) { elem.flag = 2; push(s,elem); p = p->rchild; } else { visit(p); p = NULL; // 訪問節點之後,p置為空指標,確保下次迴圈時可以直接跳過L1語句,也就是第一個if語句 } } } }