数据结构与算法 - 二叉树的遍历
二叉树的节点
二叉树的节点定义
template <class T>
class BTNode{
public:
T value; // 关键字 (键值)
BSTNode *left; // 左孩子
BSTNode *right; // 右孩子
BSTNode(T v, BTNode *l = nullptr, BTNode *r = nullptr):
value(v),left(l),right(r) {}
};
二叉树的遍历
二叉树的遍历,有三种方法:
- 递归法
- 栈迭代法
- MORRIS 迭代法
下面我们分别分析下三种方法:
递归法
三种方式中,递归法最好理解,具体实现如下:
前序遍历(递归法)
template <class T>
void BSTree<T>::BTPreOrder(BSTNode<T>& node) const
{
if(node == nullptr) return;
cout << node->value << " " ;
BTPreOrder(node->left);
BTPreOrder(node->right);
}
中序遍历(递归法)
template <class T>
void BSTree<T>::BTPMidOrder(BSTNode<T>& node) const
{
if(node == nullptr) return;
BTPMidOrder(node->left);
cout << node->value << " " ;
BTPMidOrder(node->right);
}
后序遍历(递归法)
template <class T>
void BSTree<T>::BTPostOrder(BSTNode<T>& node) const
{
if(node == nullptr) return;
BTPostOrder(node->left);
BTPostOrder(node->right);
cout << node->value << " " ;
}
栈迭代法
前序遍历(栈迭代法)
template <class T>
void BSTree<T>::BTPreOrder(BSTNode<T>& node)
{
stack<TreeNode*> nodeStack;
BSTNode<T>* node = root;
while (node || !nodeStack.empty()) {
if (node) {
nodeStack.push(node);
cout << node->value << " " ;
node = node->left;
}
else {
node = nodeStack.top();
nodeStack.pop();
node = node->right;
}
}
}
中序遍历(栈迭代法)
template <class T>
void BSTree<T>::BTMidOrder(BSTNode<T>& node)
{
stack<TreeNode*> nodeStack;
BSTNode<T>* node = root;
while (node || !nodeStack.empty()) {
if (node) {
nodeStack.push(node);
node = node->left;
}
else {
node = nodeStack.top();
cout << node->value << " " ;
nodeStack.pop();
node = node->right;
}
}
}
MORRIS 迭代法
#ifdef PRO_ORDER
BSTree<T>* BSTree<T>::rightReverse(BSTree<T>* root) {
BSTree<T>* head = nullptr;
while (root) {
BSTree<T>* next = root->right;
root->right = head;
head = root;
root = next;
}
return head;
}
void BSTree<T>::printEdge (BSTree<T>* root) {
root = rightReverse(root);
BSTree<T>* head = root;
while (head != NULL) {
result.push_back(head->val);
head = head->right;
}
root = rightReverse(root);
}
#endif
void BSTree<T>::BSTOrder()
{
if (node == nullptr) return;
BSTNode<T>* node = root;
while (node) {
if (node->left) {
/* 如果存在左子树,则需要设置索引 */
BSTNode<T>* index = node->left;
while(index->right && index->right != node)
{
index = index->right;
}
if (!index->right) {
/* 首次寻找到索引,设置索引,继续遍历左子树 */
#ifdef PRE_ORDER
cout <<node->value << " " ;
#endif
index->right = node;
node = node->left;
}
else {
/* 非首次寻找到索引,说明左子树遍历完成,根据索引去遍历右子树 */
#ifdef MID_ORDER
cout <<node->value << " " ;
#endif
node = node->right;
/* 恢复索引 */
index->right = nullptr;
#ifdef PRO_ORDER
printEdge(root);
#endif
}
}
else {
/* 没有左子树 遍历右子树 */
#ifndef PRO_ORDER
cout <<node->value << " " ;
#endif
node = node->right;
}
#ifdef PRO_ORDER
printEdge(root);
#endif
}
}