一:相关概念
二叉树是最基本的树形结构,遍历二叉树就是通过特定的顺序遍历二叉树的每一个节点。
二叉树遍历方法,前序遍历,中序遍历,后序遍历,层序遍历,前三种遍历又有递归遍历方法和非递归遍历方法。
二:代码实现
1.创建树
template<class T>
struct BinaryTreeNode//树的节点信息
{
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
T _data;
BinaryTreeNode(const T& x)
:_left(NULL),
_right(NULL),
_data(x)
{}
};
BinaryTree()//构造函数
:_root(NULL)
{}
BinaryTree(T* a, size_t n, const T& invalid)//创建树
{
size_t index = 0;
_root = CreateTree(a, n, invalid, index);
}
Node* CreateTree(T* a, size_t n, const T& invalid, size_t& index)
//树的创建 利用递归函数
{
Node* root = NULL;
if (index < n && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = CreateTree(a, n, invalid, ++index);
root->_right = CreateTree(a, n, invalid, ++index);
}
return root;
}
2.还有拷贝构造、赋值运算符重载、析构函数
赋值运算符重载有两种方式,传统写法和现代写法,现代写法直接用swap函数交换两节点内容,先拷贝构造再调用析构函数。
3.项目整体代码如下:
#pragma once
#include <iostream>
#include <stack>
#include <queue>
#include <assert.h>
using namespace std;
template<class T>
struct BinaryTreeNode
{
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
T _data;
BinaryTreeNode(const T& x)
:_left(NULL),
_right(NULL),
_data(x)
{}
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
:_root(NULL)
{}
BinaryTree(T* a, size_t n, const T& invalid)
{
size_t index = 0;
_root = CreateTree(a, n, invalid, index);
}
BinaryTree(const BinaryTree<T>& t)//拷贝构造二叉树
{
_root = _Copy(t._root);
}
//BinaryTree<T>& operator=(const BinaryTree<T>& t)//赋值运算符重载
//{
// if (this != &t)
// {
// Destroy(_root);
// _root = _Copy(t._root);
// }
// return *this;
//}
BinaryTree<T>& operator=(BinaryTree<T> t)
{
swap(_root, t._root);//先拷贝构造再调用析构函数
return *this;
}
size_t Size()//求二叉树叶子节点的个数
{
return _Size(_root);
}
void PrevOrder()//前序遍历递归法
{
_PrevOrder(_root);
cout << endl;
}
void LevelOrder()//层序遍历
{
queue<Node*> q;
if (_root)
{
q.push(_root);
while (!q.empty())
{
Node* front = q.front();
cout << front->_data << " ";
if (front->_left)
{
q.push(front->_left);
}
if (front->_right)
{
q.push(front->_right);
}
q.pop();
}
cout << endl;
}
}
void InOrder()
{
_InOrder(_root);
cout << endl;
}
void PostOrder()
{
_PostOrder(_root);
cout << endl;
}
size_t LeafSize()//叶节点数目
{
return _LeafSize(_root);
}
Node* Find(const T& x)//在二叉树中找一个数
{
return _Find(_root, x);
}
void PrevOrderNoR()//前序遍历非递归
{
if (NULL == _root)
{
return;
}
stack<Node*> s;
Node* cur = _root;
while (cur || !s.empty())//当前节点不为空或栈不为空
{
while (cur)
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cur = top->_right;
}
cout << endl;
}
void InOrderNoR()//中序非递归 利用栈实现
{
if (NULL == _root)
{
return;
}
stack<Node*> s;
Node* cur = _root;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
s.pop();
cout << top->_data<<" ";
cur = top->_right;
}
cout << endl;
}
size_t Depth()//二叉树深度
{
return _Depth(_root);
}
size_t GetKLevel(size_t k)//第K层叶子节点个数
{
return _GetKLevel(_root, k);
}
void PostOrderNoR()//后序非递归
{
if (NULL == _root)
{
return;
}
Node* cur = _root;
stack<Node*> s;
Node* prev = NULL;//保存最近访问过的一个节点
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if (top->_right == NULL || top->_right == prev)
{
cout << top->_data << " ";
prev = top;
s.pop();
}
else
{
cur = top->_right;
}
}
}
~BinaryTree()//析构函数
{
Destroy(_root);
}
protected:
Node* CreateTree(T* a, size_t n, const T& invalid, size_t& index)
{
Node* root = NULL;
if (index < n && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = CreateTree(a, n, invalid, ++index);
root->_right = CreateTree(a, n, invalid, ++index);
}
return root;
}
Node* _Copy(Node* root)
{
if (root == NULL)
{
return NULL;
}
Node* newRoot = new Node(root->_data);
newRoot->_left = _Copy(root->_left);
newRoot->_right = _Copy(root->_right);
return newRoot;
}
Node* _PrevOrder(Node* root)
{
if (root == NULL)
{
return NULL;
}
else
{
cout << root->_data << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
return root;
}
Node* _Find(Node* root, const T& x)
{
if (root == NULL)
{
return NULL;
}
if (root->_data == x)
{
return root;
}
else
{
Node* ret = _Find(root->_left,x);
if (ret)
{
return ret;
}
return _Find(root->_right,x);
}
}
size_t _Depth(Node* root)
{
if (root == NULL)
{
return 0;
}
else if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
else
{
size_t left = _Depth(root->_left)+1;
size_t right = _Depth(root->_right)+1;
return left > right ? left : right;
}
}
Node* _InOrder(Node* root)
{
if (root == NULL)
{
return NULL;
}
else
{
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
return root;
}
Node* _PostOrder(Node* root)
{
if (root == NULL)
{
return NULL;
}
else
{
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
return root;
}
size_t _GetKLevel(Node* root, size_t k)//第k层节点个数
{
assert(k > 0);
if (root == NULL)
{
return 0;
}
else if (k == 1)
{
return 1;
}
else
{
return _GetKLevel(root->_left, k - 1) + _GetKLevel(root->_right, k - 1);
}
}
size_t _LeafSize(Node* root)
{
if (root == NULL)
{
return 0;
}
else
{
if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
else
{
return _LeafSize(root->_left) + _LeafSize(root->_right);
}
}
}
size_t _Size(Node* root)
{
if (root == NULL)
{
return 0;
}
if (root->_left == NULL&&root->_right == NULL)
{
return 1;
}
else
{
return _Size(root->_left) + _Size(root->_right) + 1;
}
}
void Destroy(Node *root)//删除节点
{
if (root == NULL)
{
return;
}
Destroy(root->_left);
Destroy(root->_right);
delete root;
}
Node* _root;
};
4.测试用例
#pragma once
#include "BinaryTree.h"
void TestBinaryTree()
{
int arr[12] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 ,7,8};
BinaryTree<int> t1(arr, sizeof(arr) / sizeof(arr[0]), '#');
cout << "前序遍历:" << " ";
t1.PrevOrder();//前序遍历
cout << endl;
cout << "层序遍历:" << " ";
t1.LevelOrder();//层序遍历
cout << endl;
cout << "中序遍历:" << " ";
t1.InOrder();//中序遍历
cout << endl;
cout << "后序遍历:" << " ";
t1.PostOrder();//后序遍历
cout << endl;
cout << "前序遍历递归法:" << " ";
t1.PrevOrderNoR();
cout << endl;
cout << "中序遍历递归法:" << " ";
t1.InOrderNoR();
cout << t1.LeafSize() << endl;;
cout << t1.GetKLevel(1) << endl;
cout << t1.GetKLevel(2) << endl;
cout << t1.GetKLevel(3) << endl;
cout << t1.GetKLevel(13) << endl;
cout << t1.Find(4) << endl;
cout<<t1.Find(10)<<endl;
cout << t1.Depth() << endl;
cout << t1.Size() << endl;
t1.PostOrder();
t1.PostOrderNoR();
cout << endl;
t1.PrevOrderNoR();
t1.PrevOrder();
cout << t1.Size() << endl;
BinaryTree<int>t2(t1);
t2 = t1;
t2.PrevOrder();
t2.PostOrder();
t2.PostOrderNoR();
}
int main()
{
Te
stBinaryTree();
system("pause");
return 0;
}
当然这个测试用例还不是很全面,完整测试用例需要把每种情况都测试一遍,遍历二叉树还有线索化二叉树,可以利用将其线索化然后利用线索对其进行遍历。