定义头文件:BinTree.h
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
template <class NodeType>
struct TreeNode {
NodeType val;
TreeNode *parent;
TreeNode *lchild;
TreeNode *rchild;
TreeNode() {};
TreeNode(NodeType value) {
val = value;
parent = nullptr;
lchild = nullptr;
rchild = nullptr;
}
};
template <class NodeType>
class BinTree {
public:
BinTree():root(nullptr){}
BinTree(TreeNode<NodeType> *node) {
root = new TreeNode<NodeType>();
root->lchild = nullptr;
root->parent = nullptr;
root->rchild = nullptr;
root->val = node->val;
}
void visit(TreeNode<NodeType> &node) { cout << node.val << " "; }
TreeNode<NodeType> *getRoot() { return root; }
void makeCompleteTree();
// 递归实现遍历三种基本遍历
void preorderRecursion(TreeNode<NodeType> *node);
void inorderRecursion(TreeNode<NodeType> *node);
void postorderRecursion(TreeNode<NodeType> *node);
// 非递归实现遍历三种基本遍历、层序遍历、深度优先遍历和广度优先遍历
void preorderTraversal(TreeNode<NodeType> *node);
void inorderTraversal(TreeNode<NodeType> *node);
void inorderTraversal_2(TreeNode<NodeType> *node);
void postorderTraversal(TreeNode<NodeType> *node);
void postorderTraversal_2(TreeNode<NodeType> *node);
void levelorderTraversal(TreeNode<NodeType> *node);
void broadTraversal(TreeNode<NodeType> *node);
void depthTraversal(TreeNode<NodeType> *node);
private:
TreeNode<NodeType> *root;
};
template <class NodeType>
void BinTree<NodeType>::preorderRecursion(TreeNode<NodeType> *node) {
if (node) {
visit(*node);
preorderRecursion(node->lchild);
preorderRecursion(node->rchild);
}
}
template <class NodeType>
void BinTree<NodeType>::inorderRecursion(TreeNode<NodeType> *node) {
if (node) {
inorderRecursion(node->lchild);
visit(*node);
inorderRecursion(node->rchild);
}
}
template <class NodeType>
void BinTree<NodeType>::postorderRecursion(TreeNode<NodeType> *node) {
if (node) {
postorderRecursion(node->lchild);
postorderRecursion(node->rchild);
visit(*node);
}
}
template <class NodeType>
void BinTree<NodeType>::preorderTraversal(TreeNode<NodeType> *node) {
if (node == nullptr) return;
stack<TreeNode<NodeType>* > mystack;
mystack.push(node);
while (!mystack.empty()) {
TreeNode<NodeType> *curNode = mystack.top();
visit(*curNode);
mystack.pop();
if (curNode->rchild != nullptr) mystack.push(curNode->rchild);
if (curNode->lchild != nullptr) mystack.push(curNode->lchild);
}
}
template <class NodeType>
void BinTree<NodeType>::inorderTraversal(TreeNode<NodeType> *node) {
if (node == nullptr) return;
stack<TreeNode<NodeType>* > mystack;
TreeNode<NodeType> *curNode = node;
while (curNode || !mystack.empty()) {
if (curNode) {
mystack.push(curNode);
curNode = curNode->lchild;
}
else {
curNode = mystack.top();
visit(*curNode);
mystack.pop();
curNode = curNode->rchild;
}
}
}
// 另一种写法的中序遍历非递归实现,思路完全一样
template <class NodeType>
void BinTree<NodeType>::inorderTraversal_2(TreeNode<NodeType> *node) {
if (node == nullptr) return;
stack<TreeNode<NodeType>* > mystack;
TreeNode<NodeType> *curNode = node;
while (curNode || !mystack.empty()) {
while(curNode) {
mystack.push(curNode);
curNode = curNode->lchild;
}
curNode = mystack.top();
visit(*curNode);
mystack.pop();
curNode = curNode->rchild;
}
}
// 使用两个栈实现的后序非递归遍历算法,一个栈用于存放标记位
template<class NodeType>
void BinTree<NodeType>::postorderTraversal(TreeNode<NodeType> *node) {
if (node == nullptr) return;
stack<TreeNode<NodeType> *> mystack;
stack<int> flagstack;
mystack.push(node);
flagstack.push(0);
while (!mystack.empty()) {
TreeNode<NodeType> *curNode = mystack.top();
int curFlag = flagstack.top();
flagstack.pop();
if (curFlag == 0) {
flagstack.push(1);
if (curNode->rchild != nullptr) {
mystack.push(curNode->rchild);
flagstack.push(0);
}
if (curNode->lchild != nullptr) {
mystack.push(curNode->lchild);
flagstack.push(0);
}
}
else {
visit(*curNode);
mystack.pop();
}
}
}
// 另一种使用两个栈实现的后序非递归遍历算法,先将结点放在第一个栈中,再放入第二个栈中进行进行访问
// 需要强调的是,在第一个栈中要先把当前结点的左结点入栈,再把右结点入栈,不要弄反了顺序
template<class NodeType>
void BinTree<NodeType>::postorderTraversal_2(TreeNode<NodeType> *node) {
if (node == nullptr) return;
stack<TreeNode<NodeType> *> firststack, secondstack;
firststack.push(node);
while (!firststack.empty()) {
TreeNode<NodeType> *curNode = firststack.top();
firststack.pop();
secondstack.push(curNode);
if (curNode->lchild != nullptr) firststack.push(curNode->lchild);
if (curNode->rchild != nullptr) firststack.push(curNode->rchild);
}
while (!secondstack.empty()) {
TreeNode<NodeType> *curNode = secondstack.top();
visit(*curNode);
secondstack.pop();
}
}
// 使用队列实现的层序遍历
template <class NodeType>
void BinTree<NodeType>::levelorderTraversal(TreeNode<NodeType> *node) {
if (node == nullptr) return;
queue<TreeNode<NodeType> *> myqueue;
myqueue.push(node);
while (!myqueue.empty()) {
TreeNode<NodeType> *curNode = myqueue.front();
myqueue.pop();
visit(*curNode);
if (curNode->lchild != nullptr) myqueue.push(curNode->lchild);
if (curNode->rchild != nullptr) myqueue.push(curNode->rchild);
}
}
// 广度优先遍历本质上就是层序遍历
template <class NodeType>
void BinTree<NodeType>::broadTraversal(TreeNode<NodeType> *node) {
levelorderTraversal(node);
}
// 深度优先遍历实际上就是二叉树的先序遍历,这里直接调用先序遍历
template <class NodeType>
void BinTree<NodeType>::depthTraversal(TreeNode<NodeType> *node) {
preorderTraversal(node);
}
测试代码:main.cpp
#include "pch.h"
#include "binTree.h"
#include <iostream>
int main()
{
TreeNode<int> node1(1);
TreeNode<int> node2(2);
TreeNode<int> node3(3);
TreeNode<int> node4(4);
TreeNode<int> node5(5);
node1.lchild = &node2;
node1.rchild = &node3;
node2.lchild = nullptr;
node2.rchild = nullptr;
node3.lchild = &node4;
node3.rchild = &node5;
node4.lchild = nullptr;
node4.rchild = nullptr;
node5.lchild = nullptr;
node5.rchild = nullptr;
BinTree<int> bTree(&node1);
bTree.postorderTraversal(&node1);
}