二叉樹遍歷(遞迴與迭代)

2021-06-29 03:35:33 字數 3791 閱讀 2825

二叉樹遍歷演算法分為前序(preoredr),中序(inorder),後序(postorder)遍歷。並且可以設計遞迴型或者迭代型演算法。

[cpp]view plain

copy

print?

struct binarytreenode  

;  

struct binarytreenode

;

1.1前序遍歷

[cpp]view plain

copy

print?

void preorder(binarytreenode* proot)  

}  

void preorder(binarytreenode* proot)

}

1.2中序遍歷

[cpp]view plain

copy

print?

void inorder(binarytreenode* proot)  

}  

void inorder(binarytreenode* proot)

}

1.3後續遍歷

[cpp]view plain

copy

print?

void postorder(binarytreenode* proot)  

}  

void postorder(binarytreenode* proot)

}

二叉樹的三種遍歷**都很簡潔,但是這裡只是描述結構。根據相應的應用進行設計的時候按照這個結構寫遞迴演算法就可以了。關於遞迴演算法順便提一句很淺顯但是設計演算法的時候易忽略的一點。二叉樹的遞迴肯定是有底層的葉節點向根節點進行的。

1.4習題舉例

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換為乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中指標的指向。

分析:因為是二叉搜尋樹所以轉變的過程就是節點的左指標指向左子樹的最大值,又指標指向右子樹的最小值。可以用中序遍歷的演算法結構來程式設計。

錯誤解法:

[cpp]view plain

copy

print?

binarytreenode* findmin(binarytreenode* pnode)  

binarytreenode* findmax(binarytreenode* pnode)  

//從本質上看,這個根本就不是乙個二叉樹遞迴演算法

void convertnode(binarytreenode* pnode)  

binarytreenode* convert(binarytreenode* prootoftree)    

binarytreenode* findmin(binarytreenode* pnode)

binarytreenode* findmax(binarytreenode* pnode)

//從本質上看,這個根本就不是乙個二叉樹遞迴演算法

void convertnode(binarytreenode* pnode)

binarytreenode* convert(binarytreenode* prootoftree)

正確解法:

[cpp]view plain

copy

print?

binarytreenode* convert(binarytreenode* prootoftree)  

void convertnode(binarytreenode* pnode, binarytreenode** plastnodeinlist)    

binarytreenode* convert(binarytreenode* prootoftree)

void convertnode(binarytreenode* pnode, binarytreenode** plastnodeinlist)

為了把乙個遞迴過程改為非遞迴過程,就需要自己維護乙個輔助棧結構,記錄遍歷時的回退路徑。非遞迴的快速排序的設計依據也是這個。

2.1前序遍歷的非遞迴演算法

[cpp]view plain

copy

print?

#include

void preorder(binarytreenode* proot)  

}  }  

#includevoid preorder(binarytreenode* proot)

}}

2.2中序遍歷的非遞迴演算法

[cpp]view plain

copy

print?

#include

void inorder(binarytreenode* proot)  

//若進行到這裡左子樹為空

if (!s.empty())//stack不空時退棧,然後訪問該元素

} while (p!=null||!s.empty());  

//這裡的p==null表示右子樹為空,然後堆疊如果也空的話,才是處理完畢

}  

#includevoid inorder(binarytreenode* proot)

//若進行到這裡左子樹為空

if (!s.empty())//stack不空時退棧,然後訪問該元素

} while (p!=null||!s.empty());

//這裡的p==null表示右子樹為空,然後堆疊如果也空的話,才是處理完畢

}

2.3後序遍歷的非遞迴演算法

迭代後序遍歷比較複雜。在遍歷完左子樹時還不能訪問根節點,需要再遍歷又子樹。待右子樹遍歷完後才訪問根節點。所以在輔助棧工作記錄中必須註明節點是在左子樹還是在右子樹。

[cpp]view plain

copy

print?

//記住二叉樹後序遍歷的非遞迴呼叫需要用pair型別,因為需要記錄是左進還是右進,所以每個節點必然會進棧兩次!!!

//記住二叉樹後序遍歷的非遞迴呼叫需要用pair型別,因為需要記錄是左進還是右進,所以每個節點必然會進棧兩次!!!
[cpp]view plain

copy

print?

void postorder(binarytreenode* proot)  

bool continuel=true;     //繼續迴圈標誌,用於l改為r的時候就開始向右遍歷

while (continuel && !s.empty()) //用乙個break語句也能實現迴圈標誌continuel的功能

else

visit(p);      //如果標記為r,表示右子樹遍歷完

}  }while (!s.empty());  

}  

二叉樹的前序遍歷(遞迴 迭代)

給定乙個二叉樹,返回它的前序遍歷。示例 輸入 1,null,2,3 1 2 3 輸出 1,2,3 高階 遞迴演算法很簡單,你可以通過迭代演算法完成嗎?遞迴確實簡單,隨便寫乙個。definition for a binary tree node.public class treenode class ...

二叉樹非遞迴(迭代)方法遍歷

運用棧來實現二叉樹的前序遍歷 while 棧不為空或結點不為空 出棧的順序和中序遍歷的結果相同 void preorder node root void preorder2 node root void preorder3 node root cur s.top right s.pop 同前序遍歷一...

遞迴遍歷二叉樹

include include include 二叉鍊錶表示法 typedef struct tag bitnode bitnode 先序遍歷 void xianxuorder bitnode root 先根 printf c root data 左子樹 xianxuorder root lchil...