#include<iostream>
#include<queue>
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)
{}
};
/*
實現如下接口
1.前序輸出:void PrevOrder();
2.中序輸出:void InOrder();
3.後序輸出:void PostOrder();
4.層序輸出:void Levelorder();
5.求結點個數:size_t Size();
6.求葉子結點:size_t LeafSize();
7.求深度(距離根結點最遠的路徑):size_t Depth();
*/
template<class T>
class BinaryTree
{
public:
BinaryTree()//無參的構造函數
:_root(NULL)
{}
BinaryTree(const T*a, size_t size, const T&invalid)//有參的構造函數
{
size_t index = 0;
_root=_creatTree(a, size, index,invalid);
}
BinaryTree(const BinaryTree<T>&b)//拷貝構造
{
_root = _copy(b._root);
}
BinaryTree<T>operator=(const BinaryTree<T>&b)//賦值函數
{
if (this != &b)//檢測自賦值
{
BinaryTreeNode<T>*tmp = _copy(b._root);
_Destroy(_root);
_root = tmp;
}
return *this;
}
/*
現代寫法
BinaryTree<T>operator=( BinaryTree<T>&b)
{
if (this != &b)
{
swap(_root,b._root);
}
return *this;
}
*/
~BinaryTree()//析構
{
_Destroy(_root);
}
public:
void PrevOrder()//前序
{
_printPrevOrder(_root);
cout << endl;
}
void InOrder()//中序
{
_printInOrder(_root);
cout << endl;
}
void PostOrder()//後序
{
_printPostOrder(_root);
cout << endl;
}
void Levelorder()//層序
{
_printLevelorder(_root);
cout << endl;
}
size_t Size()//求結點個數
{
return _size(_root);
}
size_t LeafSize()//求葉結點個數
{
return _leafSize(_root);
}
size_t Depth()//求深度
{
return _depth(_root);
}
protected:
BinaryTreeNode<T>*_creatTree(const T*a, size_t size, size_t&index, const T&invalid)
{
BinaryTreeNode<T>*root = NULL;
if ((a[index] != invalid)&&index<size)
{
root = new BinaryTreeNode<T>(a[index]);
root->_left = _creatTree(a, size, ++index, invalid);
root->_right = _creatTree(a, size, ++index, invalid);
}
return root;
}
BinaryTreeNode<T> *_copy(BinaryTreeNode<T>*root)//賦值函數調用
{
BinaryTreeNode<T>*newroot = NULL;
if (root == NULL)
return NULL;
newroot= new BinaryTreeNode<T>(root->_data);
newroot->_left = _copy(root->_left);
newroot->_right = _copy(root->_right);
return newroot;
}
void _printPrevOrder(BinaryTreeNode<T>*root)//前序
{
if (root == NULL)
{
return;
}
cout << root->_data<<' ';
_printPrevOrder(root->_left);
_printPrevOrder(root->_right);
}
void _printInOrder(BinaryTreeNode<T>*root)//中序
{
if (root == NULL)
{
return;
}
_printInOrder(root->_left);
cout << root->_data<<' ';
_printInOrder(root->_right);
}
void _printPostOrder(BinaryTreeNode<T>*root)//後序
{
if (root == NULL)
{
return;
}
_printPostOrder(root->_left);
_printPostOrder(root->_right);
cout << root->_data<<' ';
}
void _printLevelorder(BinaryTreeNode<T>* root)//層序
{
if (root == NULL)
return;
queue<BinaryTreeNode<T>*> q;//利用隊來存放
q.push(root);
while (q.size())//while(!q.empty())
{
if (q.front()->_left)
{
q.push(q.front()->_left);
}
if (q.front()->_right)
{
q.push(q.front()->_right);
}
cout << q.front()->_data<<" ";
q.pop();
}
}
size_t _size(BinaryTreeNode<T>*root)//求結點個數
{
if (root == NULL)
return 0;
return _size(root->_left) + _size(root->_right) + 1;
}
size_t _leafSize(BinaryTreeNode<T>*root)//求葉子個數
{
if (root == NULL)
return 0;
if ((root->_left == NULL) && (root->_right == NULL))
{
return 1;
}
return _leafSize(root->_left) + _leafSize(root->_right);
}
size_t _depth(BinaryTreeNode<T>*root)//深度
{
int leftdepth = 0;
int rightdepth = 0;
if (root == NULL)
return 0;
else
{
leftdepth = _depth(root->_left);
rightdepth = _depth(root->_right);
/*if (leftdepth > rightdepth)
{
return leftdepth + 1;
}
else
return rightdepth + 1;*/
return leftdepth > rightdepth ? leftdepth + 1 : rightdepth + 1;
}
}
void _Destroy(BinaryTreeNode<T>*root)
{
if (root == NULL)//空樹直接返回
return;
if ((root->_left == NULL) && (root->_right == NULL))//無左右孩子
delete root;
else
{
_Destroy(root->_left);
_Destroy(root->_right);
}
}
private:
BinaryTreeNode<T>* _root;
};
思考:
//size()實現方式2
size_t BinaryTree<T>::Size()//求結點個數
{
static size_t sSize = 0;
_size(_root, sSize);
return sSize;
}
void BinaryTree<T>::_size(BinaryTreeNode<T>*root,size_t &sSize)
{
if (root == NULL)
return ;
sSize++;
_size(root->_left, sSize);
_size(root->_right, sSize);
}
//size實現方式3
size_t BinaryTree<T>::Size()//求結點個數
{
size_t size = 0;
_size(_root,size);
return size;
}
void BinaryTree<T>::_size(BinaryTreeNode<T>*root,size_t &size)
{
if (root == NULL)
return ;
size++;
_size(root->_left,size);
_size(root->_right,size);
}
遍歷方式
void _printPrevOrder(BinaryTreeNode<T>*root)//用棧來存放結點
{
if (root == NULL)
return;
stack<BinaryTreeNode<T>*> s;
s.push(root);
while (!s.empty())
{
BinaryTreeNode<T>*cur = s.top();
s.pop();
cout << cur->_data << " ";
if (cur->_right != NULL)
s.push(cur->_right);
if (cur->_left != NULL)
s.push(cur->_left);
}
}
2.中序的非遞歸實現
void _printInOrder(BinaryTreeNode<T>*root)
{
BinaryTreeNode<T>*cur = root;
stack<BinaryTreeNode<T>*>s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
BinaryTreeNode<T>*top = s.top();
cout << top->_data << " ";
cur = top->_right;
s.pop();
}
}
3.後序的非遞歸實現
void _printPostOrder(BinaryTreeNode<T>* root)
{
stack<BinaryTreeNode<T>*>s;
BinaryTreeNode<T>*cur = root;
BinaryTreeNode<T>*prev = NULL;
while (cur!=NULL || !s.empty())
{
while (cur!=NULL)
{
s.push(cur);
cur = cur->_left;
}
cur = s.top();
if (cur->_right == NULL || cur->_right == prev)
{
cout << cur->_data << " ";
prev = cur;
s.pop();
cur = NULL;
}
else
{
cur = cur->_right;
}
}