关于二叉树的概念不再赘述,看一个简单例子:
下面看代码:
#include <iostream>
#include <assert.h>
#include <stack>
#include <queue>
using namespace std;
template <class T>
struct BinaryTreeNode //结点定义
{
T _data;
BinaryTreeNode<T>* _left;
BinaryTreeNode<T>* _right;
BinaryTreeNode(const T& x)
:_data(x)
,_left(NULL)
,_right(NULL)
{}
};
template <class T>
class BinaryTree
{
public:
typedef BinaryTreeNode<T> Node;
//构造函数
BinaryTree(T* a, size_t n, size_t& index,const T& invalid = T())
{
_root = _CreateTree(a, n, index,invalid);
}
~BinaryTree()
{
_Destory(_root);
}
BinaryTree(const BinaryTree<T>& t)
{
_root=_Copy(t._root);
}
//先序遍历
void PrevOrder()
{
_PrevOrder(_root);
cout << endl;
}
//非递归先序遍历
void PrevOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur) //一直进行左子树进入,并将可以访问的结点压栈
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_left;
} //出while循环时,该结点没有左子树了
Node* top = s.top(); //top记录的是最后一个可以走的结点
s.pop(); //将其出栈
cur = top->_right; //cur指向该节点的右子树,然后回到第一个while循环当做子问题处理
}
cout << endl;
}
//中序遍历
void InOrder()
{
_InOrder(_root);
cout << endl;
}
//中序非递归
void InOrderNonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
cout << top->_data << " ";
s.pop();
cur = top->_right;
}
cout << endl;
}
//后序
void BackOrder()
{
_BackOrder(_root);
cout << endl;
}
//后序非递归
void PostOrderNonR()
{
Node* cur = _root;
Node* prev = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if (NULL == top->_right || prev == top->_right)
{
cout << top->_data << " ";
s.pop();
prev = top;
}
else
cur = top->_right;
}
cout << endl;
}
//层序遍历
void LevelOrder()
{
queue<Node*> q;
if (_root)
q.push(_root);
while (!q.empty())
{
Node* tmp = q.front();
cout << tmp->_data << " ";
q.pop();
if (tmp->_left)
q.push(tmp->_left);
if (tmp->_right)
q.push(tmp->_right);
}
cout << endl;
}
//计算节点个数
size_t Size()
{
return _Size(_root);
}
//在树中寻找x
Node* Find(const T& x)
{
queue<Node*> q;
if (_root)
q.push(_root);
while (!q.empty())
{
Node* tmp = q.front();
q.pop();
if (x == tmp->_data)
return tmp;
if (tmp->_left)
q.push(tmp->_left);
if (tmp->_right)
q.push(tmp->_right);
}
return NULL;
}
//在树中寻找x(递归法)
Node* FindR(const T& x)
{
return _FindR(_root, x);
}
//计算叶子节点个数
size_t GetLeafSize()
{
size_t count = 0;
return _GetLeafSize(_root, count);
}
size_t GetLeafSize2()
{
return _GetLeafSize2(_root);
}
//求树的深度(从1开始)
size_t Depth()
{
size_t leftdepth = 0;
size_t rightdepth = 0;
return _Depth(_root, leftdepth, rightdepth);
}
//计算第K层叶子节点的个数
size_t GetKLeafSize(size_t k)
{
assert(k > 0);
return _GetKLeafSize(_root,k);
}
//求深度(法2)
size_t Depth2()
{
return _Depth2(_root);
}
protected:
// size_t& index
// 传引用原因:递归栈中,index分别属于不同的栈帧,++index会加在不同的栈帧上的index,
// 递归退层时,index的值会恢复成所退到的递归层中的index
Node* _CreateTree(T* a, size_t n, size_t& index,const T& invalid)
{
Node* root = NULL;
if (index < n && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = _CreateTree(a, n, ++index,invalid);
root->_right = _CreateTree(a, n, ++index, invalid);
}
return root;
}
void _PrevOrder(Node* root)
{
if (root == NULL)
return;
cout << root->_data << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
void _BackOrder(Node* root)
{
if (root == NULL)
return;
_BackOrder(root->_left);
_BackOrder(root->_right);
cout << root->_data << " ";
}
size_t _Size(Node* root)
{
if (root == NULL)
return 0 ;
return _Size(root->_left) + _Size(root->_right) + 1;
}
size_t _GetLeafSize(Node* root,size_t& count)
{
if (root == NULL)
return 0;
if (root->_left == NULL&&root->_right == NULL)
count++;
_GetLeafSize(root->_left,count);
_GetLeafSize(root->_right,count);
return count;
}
size_t _GetKLeafSize(Node* root,size_t k)
{
if (NULL==root)
{
return 0;
}
if (1 == k)
{
return 1;
}
return _GetKLeafSize(root->_left, k - 1) + _GetKLeafSize(root->_right, k - 1);
}
size_t _Depth(Node* root,size_t& left,size_t& right)
{
if (root == NULL)
return 0;
if (root->_left)
{
left++;
_Depth(root->_left, left, right);
}
if (root->_right)
{
right++;
_Depth(root->_right, left, right);
}
return left > right ? left : right;
}
size_t _Depth2(Node* root)
{
if (NULL == root)
{
return 0;
}
int left = _Depth2(root->_left);
int right = _Depth2(root->_right);
return left > right ? left+1 : right+1;
}
Node* _FindR(Node* root, const T& x)
{
if (NULL == root)
return NULL;
if (x == root->_data)
{
return root;
}
Node* ret = _FindR(root->_left, x);
if (ret)
return ret;
return _FindR(root->_right, x);
}
//后序析构,不用保存当前结点的指针
void _Destory(Node* root)
{
if (NULL == root)
return;
_Destory(root->_left);
_Destory(root->_right);
delete root;
}
Node* _Copy(Node* root)
{
if (NULL == root)
return NULL;
Node* newRoot = new Node(root->_data);
newRoot->_left = _Copy(root->_left);
newRoot->_right = _Copy(root->_right);
return newRoot;
}
protected:
Node* _root;
};
void Test()
{
int a[] = { 1,2,3,'#','#',4,'#','#',5,6 };
size_t index = 0;
BinaryTree<int> t(a, sizeof(a) / sizeof(a[0]), index, '#');
cout << "先序遍历:";
t.PrevOrder();
cout << "非递归先序遍历:";
t.PrevOrderNonR();
cout << "中序遍历:";
t.InOrder();
cout << "非递归中序遍历:";
t.InOrderNonR();
cout << "后序遍历:";
t.BackOrder();
cout << "非递归后序遍历:";
t.PostOrderNonR();
cout << "层序遍历:";
t.LevelOrder();
cout << "结点个数:"<< t.Size() << endl;
BinaryTreeNode<int>* ret = NULL;
ret = t.Find(5);
cout <<"Find 5 : "<< ret->_data << endl;
cout << "计算叶节点个数:"<<t.GetLeafSize() << endl;
cout << "Depth: "<<t.Depth() << endl;
cout << "第 3 层叶节点个数:" << t.GetKLeafSize(3) << endl;
cout << "Depth2:" << t.Depth2() << endl;
ret = t.FindR(5);
cout << "FindR 5 : " << ret->_data << endl;
BinaryTree<int> t2(t);
cout << "t2 先序遍历:";
t2.PrevOrder();
}
int main()
{
Test();
return 0;
}
运行结果: