代碼:
#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; }
~linkedBinaryTree() {};
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>
void linkedBinaryTree<E>::visit(binaryTreeNode<E> *node) const
{
//訪問節點*node, 僅輸出element
cout << node->element << " ";
}
template<typename E>
void linkedBinaryTree<E>::InputBinaryNode()
{
E elem;
cout << "!!!注意:(1)#表示空節點;(2)請在輸入的字符串末尾加0,作爲輸入結束的標誌!" << endl;
while (cin >> elem && elem != '0')
{
vecNode.push_back(elem);
}
}
template<typename E>
void linkedBinaryTree<E>::preCreateBinaryTree(binaryTreeNode<E> *&node)
{
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>
int linkedBinaryTree<E>::height(binaryTreeNode<E> *&node) const
{
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>
void linkedBinaryTree<E>::preOrder(binaryTreeNode<E> *node)
{
//根節點——左子樹——右子樹
if (node)
{
visit(node);
preOrder(node->leftChild);
preOrder(node->rightChild);
}
}
template<typename E>
void linkedBinaryTree<E>::inOrder(binaryTreeNode<E> *node)
{
//左子樹——根節點——右子樹
if (node)
{
inOrder(node->leftChild);
visit(node);
inOrder(node->rightChild);
}
}
template<typename E>
void linkedBinaryTree<E>::postOrder(binaryTreeNode<E> *node)
{
//左子樹——右子樹——根節點
if (node)
{
postOrder(node->leftChild);
postOrder(node->rightChild);
visit(node);
}
}
template<typename E>
void linkedBinaryTree<E>::Iter_preOrder(binaryTreeNode<E> *node)
{
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>
void linkedBinaryTree<E>::Iter_inOrder(binaryTreeNode<E> *node)
{
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>
void linkedBinaryTree<E>::Iter_postOrder(binaryTreeNode<E> *node)
{
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[])
{
linkedBinaryTree<char> LBT;
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;
}
注:中間註釋代碼部分會造成,純虛函數沒有強制替代項的錯誤。
結果 :
注:上述代碼是在我的舊文基礎上改進的http://blog.csdn.net/u014033518/article/details/38844583