|
費(fèi)了兩天時(shí)間寫的,包括前中后序遍歷的遞歸和非遞歸算法,還有層序遍歷總共2*3 + 1 = 7中遍歷二叉樹(shù)的算法,感覺(jué)其中后序遍歷的非遞歸算法比較困難,想了很久最后的實(shí)現(xiàn)還是不夠優(yōu)雅,請(qǐng)大家指正~~
總共三個(gè)文件,一個(gè)頭文件,一個(gè)對(duì)應(yīng)的cpp文件,還有一個(gè)用于測(cè)試的文件.
頭文件:
 /**//********************************************************************
????created:????2006/07/04
????filename:?????BinaryTree.h
????author:????????李創(chuàng)
????????????????http://www.shnenglu.com/converse/

????purpose:????演示二叉樹(shù)的算法
*********************************************************************/

#ifndef?BinaryTree_H
#define?BinaryTree_H

#include?<stdlib.h>
#include?<stack>

class?BinaryTree
  {
private:
????typedef?int?Item;
????typedef?struct?TreeNode
 ???? {
????????Item????????Node;
????????TreeNode*???pRight;
????????TreeNode*???pLeft;

????????TreeNode(Item?node?=?0,?TreeNode*?pright?=?NULL,?TreeNode*?pleft?=?NULL)
????????????:?Node(node)
????????????,?pRight(pright)
????????????,?pLeft(pleft)
 ???????? {
????????}

????}TreeNode,?*PTreeNode;

public:
????enum?TraverseType
 ???? {
????????PREORDER????=?0,????????//?前序
????????INORDER????????=?1,????????//?中序
????????POSTORDER????=?2,????????//?后序
????????LEVELORDER????=?3????????????//?層序
????};

????BinaryTree(Item?Array[],?int?nLength);
????~BinaryTree();

????PTreeNode?GetRoot()
 ???? {
????????return?m_pRoot;
????}

????//?遍歷樹(shù)的對(duì)外接口
????//?指定遍歷類型和是否是非遞歸遍歷,默認(rèn)是遞歸遍歷
????void?Traverse(TraverseType?traversetype,?bool?bRec?=?true);

private:
????PTreeNode???CreateTreeImpl(Item?Array[],?int?nLength);
????void????????DetroyTreeImpl(PTreeNode?pTreenode);

????void????????PreTraverseImpl(PTreeNode?pTreenode);????????//?遞歸前序遍歷樹(shù)
????void????????InTraverseImpl(PTreeNode?pTreenode);????????//?遞歸中序遍歷樹(shù)
????void????????PostTraverseImpl(PTreeNode?pTreenode);????????//?遞歸后序遍歷樹(shù)

????void????????NoRecPreTraverseImpl(PTreeNode?pTreenode);????//?非遞歸前序遍歷樹(shù)
????void????????NoRecInTraverseImpl(PTreeNode?pTreenode);????//?非遞歸中序遍歷樹(shù)
????void????????NoRecPostTraverseImpl(PTreeNode?pTreenode);????//?非遞歸后序遍歷樹(shù)

????void????????LevelTraverseImpl(PTreeNode?pTreenode);

????PTreeNode???m_pRoot;????????//?根結(jié)點(diǎn)

????//?采用STL里面的stack作為模擬保存鏈表結(jié)點(diǎn)的stack容器
????typedef?std::stack<BinaryTree::PTreeNode>?TreeNodeStack;
};

#endif
實(shí)現(xiàn)文件:
 /**//********************************************************************
????created:????2006/07/04
????filename:?????BinaryTree.cpp
????author:????????李創(chuàng)
????????????????http://www.shnenglu.com/converse/

????purpose:????演示二叉樹(shù)的算法
*********************************************************************/

#include?<iostream>
#include?<assert.h>
#include?<queue>
#include?"BinaryTree.h"

BinaryTree::BinaryTree(Item?Array[],?int?nLength)
????:?m_pRoot(NULL)
  {
????assert(NULL?!=?Array);
????assert(nLength?>?0);

????m_pRoot?=?CreateTreeImpl(Array,?nLength);
}

BinaryTree::~BinaryTree()
  {
????DetroyTreeImpl(m_pRoot);
}

//?按照中序遞歸創(chuàng)建樹(shù)
BinaryTree::PTreeNode?BinaryTree::CreateTreeImpl(Item?Array[],?int?nLength)
  {
????int?mid?=?nLength?/?2;
????PTreeNode?p?=?new?TreeNode(Array[mid]);

????if?(nLength?>?1)
 ???? {
????????p->pLeft????=?CreateTreeImpl(Array,?nLength?/?2);
????????p->pRight???=?CreateTreeImpl(Array?+?mid?+?1,?nLength?/?2?-?1);
????}

????return?p;
}

void?BinaryTree::DetroyTreeImpl(PTreeNode?pTreenode)
  {
????if?(NULL?!=?pTreenode->pLeft)
 ???? {
????????DetroyTreeImpl(pTreenode->pLeft);
????}
????if?(NULL?!=?pTreenode->pRight)
 ???? {
????????DetroyTreeImpl(pTreenode->pRight);
????}

????delete?pTreenode;
????pTreenode?=?NULL;
}

//?遍歷樹(shù)的對(duì)外接口
//?指定遍歷類型和是否是非遞歸遍歷,默認(rèn)是遞歸遍歷
 void?BinaryTree::Traverse(TraverseType?traversetype,?bool?bRec?/**//*=?true*/)
  {
????switch?(traversetype)
 ???? {
????case?PREORDER:????//?前序
 ???????? {????????????
????????????if?(true?==?bRec)
 ???????????? {
????????????????std::cout?<<?"遞歸前序遍歷樹(shù)\n";
????????????????PreTraverseImpl(m_pRoot);
????????????}
????????????else
 ???????????? {
????????????????std::cout?<<?"非遞歸前序遍歷樹(shù)\n";
????????????????NoRecPreTraverseImpl(m_pRoot);
????????????}
????????}
????????break;

????case?INORDER:????//?中序
 ???????? {????????????
????????????if?(true?==?bRec)
 ???????????? {
????????????????std::cout?<<?"遞歸中序遍歷樹(shù)\n";
????????????????InTraverseImpl(m_pRoot);
????????????}
????????????else
 ???????????? {
????????????????std::cout?<<?"非遞歸中序遍歷樹(shù)\n";
????????????????NoRecInTraverseImpl(m_pRoot);
????????????}
????????}
????????break;

????case?POSTORDER:????//?后序
 ???????? {????????????
????????????if?(true?==?bRec)
 ???????????? {
????????????????std::cout?<<?"遞歸后序遍歷樹(shù)\n";
????????????????PostTraverseImpl(m_pRoot);
????????????}
????????????else
 ???????????? {
????????????????std::cout?<<?"非遞歸后序遍歷樹(shù)\n";
????????????????NoRecPostTraverseImpl(m_pRoot);
????????????}
????????}
????????break;

????case?LEVELORDER:????//?層序
 ???????? {
????????????std::cout?<<?"層序遍歷樹(shù)\n";
????????????LevelTraverseImpl(m_pRoot);
????????}
????}

????std::cout?<<?std::endl;
}

//?遞歸前序遍歷樹(shù)
void?BinaryTree::PreTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????std::cout?<<?"Item?=?"?<<?pTreenode->Node?<<?std::endl;

????PreTraverseImpl(pTreenode->pLeft);

????PreTraverseImpl(pTreenode->pRight);
}

//?非遞歸前序遍歷樹(shù)
void?BinaryTree::NoRecPreTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????TreeNodeStack?NodeStack;
????PTreeNode?pNode;
????NodeStack.push(pTreenode);

????while?(!NodeStack.empty())
 ???? {
????????while?(NULL?!=?(pNode?=?NodeStack.top()))????//?向左走到盡頭
 ???????? {
????????????std::cout?<<?"Item?=?"?<<?pNode->Node?<<?std::endl;????//?訪問(wèn)當(dāng)前結(jié)點(diǎn)
????????????NodeStack.push(pNode->pLeft);????????????????????//?左子樹(shù)根結(jié)點(diǎn)入棧
????????}
????????NodeStack.pop();????????????????????????????????????//?左子樹(shù)根結(jié)點(diǎn)退棧
????????if?(!NodeStack.empty())
 ???????? {
????????????pNode?=?NodeStack.top();
????????????NodeStack.pop();????????????????????????????????//?當(dāng)前結(jié)點(diǎn)退棧
????????????NodeStack.push(pNode->pRight);????????????????//?當(dāng)前結(jié)點(diǎn)的右子樹(shù)根結(jié)點(diǎn)入棧
????????}
????}
}

//?中序遍歷樹(shù)
//?中序遍歷輸出的結(jié)果應(yīng)該和用來(lái)初始化樹(shù)的數(shù)組的排列順序一致
void?BinaryTree::InTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????if?(NULL?!=?pTreenode->pLeft)
 ???? {
????????InTraverseImpl(pTreenode->pLeft);
????}

????std::cout?<<?"Item?=?"?<<?pTreenode->Node?<<?std::endl;

????if?(NULL?!=?pTreenode->pRight)
 ???? {
????????InTraverseImpl(pTreenode->pRight);
????}
}

//?非遞歸中序遍歷樹(shù)
void?BinaryTree::NoRecInTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????TreeNodeStack?NodeStack;
????PTreeNode?pNode;
????NodeStack.push(pTreenode);

????while?(!NodeStack.empty())
 ???? {
????????while?(NULL?!=?(pNode?=?NodeStack.top()))????//?向左走到盡頭
 ???????? {
????????????NodeStack.push(pNode->pLeft);
????????}

????????NodeStack.pop();

????????if?(!NodeStack.empty()?&&?NULL?!=?(pNode?=?NodeStack.top()))
 ???????? {
????????????std::cout?<<?"Item?=?"?<<?pNode->Node?<<?std::endl;
????????????NodeStack.pop();
????????????NodeStack.push(pNode->pRight);
????????}
????}
}

//?后序遍歷樹(shù)
void?BinaryTree::PostTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????if?(NULL?!=?pTreenode->pLeft)
 ???? {
????????PostTraverseImpl(pTreenode->pLeft);
????}

????if?(NULL?!=?pTreenode->pRight)
 ???? {
????????PostTraverseImpl(pTreenode->pRight);
????}

????std::cout?<<?"Item?=?"?<<?pTreenode->Node?<<?std::endl;
}

//?非遞歸后序遍歷樹(shù)
void?BinaryTree::NoRecPostTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????TreeNodeStack?NodeStack;
????PTreeNode?pNode1,?pNode2;
????NodeStack.push(pTreenode);
????pNode1?=?pTreenode->pLeft;
????
????bool?bVisitRoot?=?false;????????????//?標(biāo)志位,是否訪問(wèn)過(guò)根結(jié)點(diǎn)
????while?(!NodeStack.empty())
 ???? {
????????while?(NULL?!=?pNode1)????????????//?向左走到盡頭
 ???????? {
????????????NodeStack.push(pNode1);
????????????pNode1?=?pNode1->pLeft;
????????}

????????pNode1?=?NodeStack.top();
????????NodeStack.pop();

????????if?(NULL?==?pNode1->pRight)????????????//?如果沒(méi)有右子樹(shù)就是葉子結(jié)點(diǎn)
 ???????? {
????????????std::cout?<<?"Item?=?"?<<?pNode1->Node?<<?std::endl;
????????????pNode2?=?pNode1;
????????????pNode1?=?NodeStack.top();

????????????if?(pNode2?==?pNode1->pRight)????//?如果這個(gè)葉子結(jié)點(diǎn)是右子樹(shù)
 ???????????? {
????????????????std::cout?<<?"Item?=?"?<<?pNode1->Node?<<?std::endl;
????????????????NodeStack.pop();
????????????????pNode1?=?NULL;
????????????}
????????????else????????????????????????????//?否則訪問(wèn)右子樹(shù)
 ???????????? {
????????????????pNode1?=?pNode1->pRight;
????????????}
????????}
????????else????????????????????????????????//?訪問(wèn)右子樹(shù)
 ???????? {
????????????if?(pNode1?==?pTreenode?&&?true?==?bVisitRoot)????//?如果已經(jīng)訪問(wèn)過(guò)右子樹(shù)那么就退出
 ???????????? {
????????????????std::cout?<<?"Item?=?"?<<?pNode1->Node?<<?std::endl;
????????????????return;
????????????}
????????????else
 ???????????? {
????????????????if?(pNode1?==?pTreenode)
 ???????????????? {
????????????????????bVisitRoot?=?true;
????????????????}

????????????????NodeStack.push(pNode1);
????????????????pNode1?=?pNode1->pRight;
????????????}
????????}
????}
}

//?按照樹(shù)的層次從左到右訪問(wèn)樹(shù)的結(jié)點(diǎn)
void?BinaryTree::LevelTraverseImpl(PTreeNode?pTreenode)
  {
????if?(NULL?==?pTreenode)
????????return;

????//?層序遍歷用于保存結(jié)點(diǎn)的容器是隊(duì)列
????std::queue<PTreeNode>?NodeQueue;
????PTreeNode?pNode;
????NodeQueue.push(pTreenode);

????while?(!NodeQueue.empty())
 ???? {
????????pNode?=?NodeQueue.front();
????????NodeQueue.pop();
????????std::cout?<<?"Item?=?"?<<?pNode->Node?<<?std::endl;

????????if?(NULL?!=?pNode->pLeft)
 ???????? {
????????????NodeQueue.push(pNode->pLeft);????
????????}
????????if?(NULL?!=?pNode->pRight)
 ???????? {
????????????NodeQueue.push(pNode->pRight);
????????}????
????}
}
測(cè)試文件:  /**//********************************************************************
????created:????2006/07/04
????filename:?????main.cpp
????author:????????李創(chuàng)
????????????????http://www.shnenglu.com/converse/

????purpose:????測(cè)試二叉樹(shù)的算法
*********************************************************************/

#include?"BinaryTree.h"

#include?<stdio.h>
#include?<stdlib.h>
#include?<time.h>
#include?<iostream>

void?DisplayArray(int?array[],?int?length)
  {
????int?i;

????for?(i?=?0;?i?<?length;?i++)
 ???? {
????????printf("array[%d]?=?%d\n",?i,?array[i]);
????}
}

void?CreateNewArray(int?array[],?int?length)
  {
????for?(int?i?=?0;?i?<?length;?i++)
 ???? {
????????array[i]?=?rand()?%?256?+?i;
????}
}

int?main()
  {
????int?array[10];
????srand(time(NULL));

????//?創(chuàng)建數(shù)組
????CreateNewArray(array,?10);
????DisplayArray(array,?10);

????BinaryTree?*pTree?=?new?BinaryTree(array,?10);

????//?測(cè)試前序遍歷
????pTree->Traverse(BinaryTree::PREORDER);
????std::cout?<<?"root?=?"?<<?pTree->GetRoot()->Node?<<?std::endl;
????std::cout?<<?"root->left?=?"?<<?pTree->GetRoot()->pLeft->Node?<<?std::endl;
????std::cout?<<?"root->right?=?"?<<?pTree->GetRoot()->pRight->Node?<<?std::endl;
????pTree->Traverse(BinaryTree::PREORDER,?false);
????
????//?測(cè)試中序遍歷
????pTree->Traverse(BinaryTree::INORDER);
????std::cout?<<?"root?=?"?<<?pTree->GetRoot()->Node?<<?std::endl;
????std::cout?<<?"root->left?=?"?<<?pTree->GetRoot()->pLeft->Node?<<?std::endl;
????std::cout?<<?"root->right?=?"?<<?pTree->GetRoot()->pRight->Node?<<?std::endl;
????pTree->Traverse(BinaryTree::INORDER,?false);
????//?測(cè)試后序遍歷
????pTree->Traverse(BinaryTree::POSTORDER);
????std::cout?<<?"root?=?"?<<?pTree->GetRoot()->Node?<<?std::endl;
????std::cout?<<?"root->left?=?"?<<?pTree->GetRoot()->pLeft->Node?<<?std::endl;
????std::cout?<<?"root->right?=?"?<<?pTree->GetRoot()->pRight->Node?<<?std::endl;
????pTree->Traverse(BinaryTree::POSTORDER,?false);
????//?測(cè)試層序遍歷
????pTree->Traverse(BinaryTree::LEVELORDER);

????system("pause");
????
????delete?pTree;

????return?0;
}

|