# 笔记九：二叉树的创建、递归与非递归版前序、中序、后序查找、树高和节点判断

#include<iostream>
#include<vector>
#include<stack>
using namespace std;

template<typename T>
struct binaryTreeNode{
T element;
binaryTreeNode<T>  *leftChild;      //左子树
binaryTreeNode<T>  *rightChild;     //右子树
binaryTreeNode() {
leftChild = rightChild = NULL;
}
binaryTreeNode(const T& theElement)
{
element = theElement;
leftChild = rightChild = NULL;
}
binaryTreeNode(const T&  theElement, binaryTreeNode *theLeftChild, binaryTreeNode *theRightChild)
{
element(theElement);
leftChild = theLeftChild;
rightChild = theRightChild;
}
};

template <typename T>
class binaryTree{
public:
virtual ~binaryTree() {}
virtual bool empty() const = 0;
virtual int size() const = 0;
virtual void visit(T *) const = 0;
virtual void InputBinaryNode() = 0;
virtual void preCreateBinaryTree(T *&) = 0;

/*virtual void preOrder(binaryTreeNode<T> *node) = 0;
virtual void inOrder(binaryTreeNode<T> *node) = 0;
virtual void postOrder(binaryTreeNode<T> *node) = 0;

virtual void Iter_preOrder(binaryTreeNode<T> *node) = 0;
virtual void Iter_inOrder(binaryTreeNode<T> *node) = 0;
virtual void Iter_postOrder(binaryTreeNode<T> *node) = 0;*/
virtual void preOrder(T *) = 0;
virtual void inOrder(T *) = 0;
virtual void postOrder(T *) = 0;

virtual void Iter_preOrder(T *) = 0;
virtual void Iter_inOrder(T *) = 0;
virtual void Iter_postOrder(T *) = 0;

};

template<typename E>
class linkedBinaryTree : public binaryTree<binaryTreeNode<E> >
{
public:
linkedBinaryTree(){ root = NULL; treeSize = 0; }
bool empty() const { return treeSize == 0; }
int size() const { return treeSize; }
void visit(binaryTreeNode<E> *node) const;
void InputBinaryNode();
void preCreateBinaryTree(binaryTreeNode<E> *&node);
int height(binaryTreeNode<E> *&node) const;

void preOrder(binaryTreeNode<E> *node);
void inOrder(binaryTreeNode<E> *node);
void postOrder(binaryTreeNode<E> *node);

void Iter_preOrder(binaryTreeNode<E> *node);
void Iter_inOrder(binaryTreeNode<E> *node);
void Iter_postOrder(binaryTreeNode<E> *node);

private:
binaryTreeNode<E> *root;
int treeSize;
vector<E> vecNode;
};

template<typename E>
{
//访问节点*node, 仅输出element
cout << node->element << " ";
}

template<typename E>
{
E elem;
cout << "！！！注意：（1）#表示空节点；（2）请在输入的字符串末尾加0，作为输入结束的标志！" << endl;
while (cin >> elem && elem != '0')
{
vecNode.push_back(elem);
}
}

template<typename E>
{
vector<E>::iterator it = vecNode.begin();
if (it != vecNode.end())
{
if (*it == '#')
{
node = NULL;
vecNode.erase(it);
}
else{
node = new binaryTreeNode<E>(*it);  //生成根节点
treeSize++;
vecNode.erase(it);
preCreateBinaryTree(node->leftChild);   //构造左子树
preCreateBinaryTree(node->rightChild);  //构造右子树
}
}
else{
node = NULL;
}
}

template<typename E>
{
if (!node)
{
return 0;
}

int hl = height(node->leftChild);   //左子树的高
int hr = height(node->rightChild);  //右子树的高
if (hl > hr)
{
return ++hl;
}
else{
return ++hr;
}

}

template<typename E>
{
//根节点——左子树——右子树
if (node)
{
visit(node);
preOrder(node->leftChild);
preOrder(node->rightChild);
}

}

template<typename E>
{
//左子树——根节点——右子树
if (node)
{
inOrder(node->leftChild);
visit(node);
inOrder(node->rightChild);
}

}

template<typename E>
{
//左子树——右子树——根节点
if (node)
{
postOrder(node->leftChild);
postOrder(node->rightChild);
visit(node);
}

}

template<typename E>
{
stack<binaryTreeNode<E>* > stk;     //存储树节点
binaryTreeNode<E> * currNode = node;
while (currNode || (!stk.empty()))
{
if (currNode)
{
visit(currNode);            //访问根节点
stk.push(currNode);
currNode = currNode->leftChild; //遍历左子树
}
else{
currNode = stk.top();       //节点入栈前已被访问，故无需再次访问
stk.pop();
currNode = currNode->rightChild;
}
}

}

template<typename E>
{
stack<binaryTreeNode<E>* > stk;
binaryTreeNode<E>* currNode = node;
while (currNode || (!stk.empty()))
{
if (currNode)
{
stk.push(currNode);     //先将左子树全部压入栈
currNode = currNode->leftChild;
}
else{
currNode = stk.top();
stk.pop();
visit(currNode);        //访问根节点
currNode = currNode->rightChild;
}
}
}

template<typename E>
{
stack<binaryTreeNode<E>* > stk;
binaryTreeNode<E>* currNode = node, *rightNode = node;
while (currNode || (!stk.empty()))
{
if (currNode)
{
stk.push(currNode);     //遍历左子树
currNode = currNode->leftChild;
}
else{
currNode = stk.top();
currNode = currNode->rightChild;    //遍历右子树
if (!currNode)          //此时栈顶元素的左孩子、右孩子均为空，即为叶子节点
{
rightNode = stk.top();
stk.pop();
visit(rightNode);   //访问叶子节点
//若刚被访问的叶子节点是此时栈顶元素的右孩子，则说明左、右子树均被遍历完
//循环的目的是为了找到最终的父结点，当前所有已访问的节点是作为其左子树的节点而存在
while ((!stk.empty()) && (stk.top()->rightChild == rightNode))
{
rightNode = stk.top();  //由于该节点的右节点已被访问，说明完成了左右子树的遍历
stk.pop();
visit(rightNode);       //叶子节点已经被访问，则最后访问根节点
}
if (!stk.empty())           //刚被访问的是此时栈顶元素的左孩子，则右孩子还未入栈
{
currNode = stk.top();
currNode = currNode->rightChild;
}
}
}//else
}
}

int main(int argc, char* argv[])
{
binaryTreeNode<char>* root;
LBT.InputBinaryNode();
LBT.preCreateBinaryTree(root);
cout << "二叉树的总节点数为：" << LBT.size() << endl;
cout << "二叉树的高度为:"<< LBT.height(root) << endl;

cout << "\n前序遍历二叉树（递归）:" << endl;
LBT.preOrder(root);
cout << "\n中序遍历二叉树（递归）:" << endl;
LBT.inOrder(root);
cout << "\n后序遍历二叉树（递归）:" << endl;
LBT.postOrder(root);

cout << "\n\n前序遍历二叉树（非递归）:" << endl;
LBT.Iter_preOrder(root);
cout << "\n中序遍历二叉树（非递归）:" << endl;
LBT.Iter_inOrder(root);
cout << "\n后序遍历二叉树（非递归）:" << endl;
LBT.Iter_postOrder(root);

return 0;
}

• 本文已收录于以下专栏：

## 笔记九：二叉树的创建、递归与非递归版前序、中序、后序查找、树高和节点判断

• u014033518
• 2016年05月30日 16:23
• 818

## typedef void (*Fun) (void) 的理解——函数指针——typedef函数指针

• u014221279
• 2016年03月25日 16:06
• 5005

## 二叉树的创建与前序、中序和后序的递归与非递归调用

#include #include #include #include using namespace std; typedef char ElemType; class BiTNode { fr...
• u014033518
• 2014年08月26日 10:51
• 583

## 二叉树前序中序建立和后序中序建立

• LsMrSUN
• 2016年08月08日 10:59
• 1982

## 【工程】二叉树已知前序/中序的顺序，构造树的递归等实现

• mig_davidli
• 2013年04月27日 19:31
• 1259

## 二叉树之线索链表

• u011677050
• 2016年12月02日 18:21
• 1214

## 树的学习——（递归构建二叉树、递归非递归前序中序后序遍历二叉树、根据前序序列、中序序列构建二叉树）

• zinss26914
• 2012年12月29日 10:46
• 7660

## 二叉树的创建 先序 中序 后续 递归和非递归遍历

• u011561690
• 2015年04月15日 19:00
• 876

## 数据结构——二叉树1（c++）

• cckevincyh
• 2015年06月21日 17:30
• 456

## typedef void(*Fun)(void);

• bigpudding24
• 2016年02月25日 18:14
• 948

举报原因： 您举报文章：笔记九：二叉树的创建、递归与非递归版前序、中序、后序查找、树高和节点判断 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)