1 原理分析
线索化意义:
二叉树是非线性结构,遍历二叉树都是通过递归或者用栈辅助非递归来遍历的。
1)不借用栈或者队列来实现遍历的非递归,还有一种方法是线索化。
2)为了实现迭代器,面向对象。
如果我们知道一个节点的前驱和后继,那么我们就可直接遍历二叉树。
设置二叉树节点的前驱和后继,就是线索化二叉树,我们利用指向左右子树的空指针存放节点的前驱和后继。
线索化设计思路:
遍历二叉树,当遍历到一个节点的左节点或右节点为空时,设置它的前驱和后继,那么访问时直接可根据节点的前驱和后继来进行访问
1.1 中序线索化和遍历
1.2 前序线索化和遍历
1.3 后续线索化和遍历
2 代码实现:
//BinaryTreeNodeThd.h
#pragma once
#include<iostream>
#include<string.h>
#include<assert.h>
enum PointerTag { THREAD, LINK };
template<class T>
struct BinaryTreeNodeThd
{
T _data; // 数据
BinaryTreeNodeThd* _left; // 左孩子
BinaryTreeNodeThd* _right; // 右孩子
PointerTag _leftTag; // 左孩子线索标志
PointerTag _rightTag; // 右孩子线索标志
BinaryTreeNodeThd* _parent;//用于后序遍历
BinaryTreeNodeThd(const T& d)
:_data(d)
, _left(NULL)
, _right(NULL)
, _leftTag(LINK)
, _rightTag(LINK)
, _parent(NULL)
{}
};
// 基类迭代器
template<class T>
struct __BinaryTreeIterator
{
typedef BinaryTreeNodeThd<T> Node;
typedef __BinaryTreeIterator<T> Self;
Node* _node;
__BinaryTreeIterator(Node* node)
:_node(node)
{}
T& operator *()
{
return _node->_data;
}
T* operator ->()
{
return &(operator *());
}
bool operator =(const Self& s)
{
return _node == s._node;
}
bool operator !=(const Self& s)
{
return _node != s._node;
}
virtual Self& operator++()=0;
};
template<class T>
struct __BinaryTreeInIterator : public __BinaryTreeIterator<T>//中序迭代器
{
typedef BinaryTreeNodeThd<T> Node;
typedef __BinaryTreeInIterator<T> Self;
__BinaryTreeInIterator(Node* node)
:__BinaryTreeIterator(node)
{ }
Self& operator++()
{