二叉树是一种非线性结构,用途广泛。二叉树的每个结点的度都不大于2,所以一般用二叉链表来实现二叉树。
二叉树可以分为根结点,左子树和右子树,左子树、右子树依然这么划分,所以用递归实现二叉树的逻辑是比较简单的,只需不断对子树进行划分即可。
#include<iostream>
#include<assert.h>
#include<queue>
using namespace std;
template <class T>
struct BinaryTreeNode
{
BinaryTreeNode* _left;
BinaryTreeNode* _right;
T _data;
BinaryTreeNode(const T& data)
: _left(NULL)
, _right(NULL)
, _data(data)
{}
};
template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
: _root()
{}
~BinaryTree()
{
_Distory(_root);
}
BinaryTree(const T* array, size_t size, const T& invalid)
{
size_t index = 0;//定义下标来遍历数组
_root = _CreatTree(array, size, index, invalid);
}
BinaryTree(BinaryTree<T> &t) //拷贝构造
{
_root = _Copy(t._root);
}
BinaryTree& operator = (BinaryTree<T>&t)
{
if (this != t)
{
BinaryTree<T>tmp(t);
swap(_root, tmp._root);
}
return *this;
}
//叶子节点的个数
size_t Leaf()
{
return _leaf(_root);
}
//节点的总个数
size_t Size()
{
return _size(_root);
}
//树的深度
size_t Depth()
{
return _depth(_root);
}
//前序遍历
void PreveOrder()
{
_PrevePrint(_root);
cout << endl;
}
//中序遍历
void InOrder()
{
_InPrint(_root);
cout << endl;
}
//后序遍历
void BackOrder()
{
_BackPrint(_root);
cout << endl;
}
//层序遍历
void TierOrder()
{
_TierPrint(_root);
cout << endl;
}
//二叉树的镜像——>递归
void MirrorBinaryTree()
{
_MirrorBinaryTree(_root);
}
// 求二叉树的镜像--->非递归
void MirrorBinaryTree_Nor()
{
_MirrorBinaryTree_Nor(_root);
}
// 获取第k层节点的个数
size_t GetKLevelNodeCount(size_t K)
{
return _GetKLevelNodeCount(_pRoot, K);
}
// 值为data的结点是否存在
Node* Find(const T& data)
{
return _Find(_root, data);
}
// 判断一个结点是否在二叉树中
bool IsNodeInTree(Node* pNode)
{
return _IsNodeInTree(_root, pNode);
}
// 获取指定结点的双亲
Node* GetParent(Node* pNode)
{
return _GetParent(_pRoot, pNode);
}
// 获取二叉树的左孩子
Node* GetLeftChild(Node* pCur)
{
return _GetLeftChild(_root, pCur);
}
// 获取二叉树的右孩子
Node* GetRightChild(Node* pCur)
{
return _GetRightChild(_root, pCur);
}
// 判断一棵二叉树是否为完全二叉树
bool IsCompleteBinaryTree()
{
return _IsCompleteBinaryTree(_root);
}
// 获取二叉树中第K层结点的个数
size_t GetKLevelNodeCount(int K)
{
return _getKlevelNodeCount(_root, K);
}
// 查找data是否在二叉树中
Node* Find( const T& data)
{
return _Find(Node* _root, const T& data);
}
protected:
Node* _CreatTree(const T* array, size_t size, size_t& index, const T& invalid)
{
assert(array);
Node* root = NULL;
if (index < size && array[index] != invalid)
{
root = new Node(array[index]);
root->_left = _CreatTree(array, size, ++index, invalid);
root->_right = _CreatTree(array, size, ++index, invalid);
}
return root;
}
Node* _Copy(Node* root)
{
Node*cur = root;
Node*tmp = NULL;
if (cur)
{
tmp = new Node(cur->_data);
tmp->_left = _Copy(cur->_left);
tmp->_right = _Copy(cur->_right);
}
return tmp;
}
void _Distory(Node* root)
{
Node* tmp = root;
if (tmp)
{
_Distory(tmp->_left);
_Distory(tmp->_right);
delete(tmp);
tmp = NULL;
}
}
size_t _leaf(Node* root)
{
Node* cur = root;
if (cur == NULL)
return 0;
if (cur->_left == NULL && cur->_right == NULL)
return 1;
return _leaf(cur->_left) + _leaf(cur->_right);
}
size_t _size(Node* root)
{
if (root == NULL)
return 0;
return 1 + _size(root->_left) + _size(root->_right);
}
size_t _depth(Node* root)
{
Node* cur = root;
if (cur == NULL)
return 0;
return 1 + (_depth(cur->_left) > _depth(cur->_right) ? _depth(cur->_left) : _depth(cur->_right));
}
void _PrevePrint(Node* root)
{
Node* cur = root;
if (cur)
{
cout << cur->_data << " ";
_PrevePrint(cur->_left);
_PrevePrint(cur->_right);
}
}
void _InPrint(Node* root)
{
Node* cur = root;
if (cur)
{
_InPrint(cur->_left);
cout << cur->_data << " ";
_InPrint(cur->_right);
}
}
void _BackPrint(Node* root)
{
Node* cur = root;
if (cur)
{
_BackPrint(cur->_left);
_BackPrint(cur->_right);
cout << cur->_data << " ";
}
}
void _TierPrint(Node* root)
{
queue<Node*> q;
Node* cur = root;
q.push(cur);
while (!q.empty() && cur)
{
Node* cur = q.front();
cout << cur->_data << " ";
q.pop();
if (cur->_left)
q.push(cur->_left);
if (cur->_right)
q.push(cur->_right);
}
}
size_t _getKlevelNodeCount(Node* root, size_t k)
{
if (root == NULL || k > Depth())
return 0;
if (k == 1)
return 1;
return _getKlevelNodeCount(root->_left, k - 1) + _getKlevelNodeCount(root->_right, k - 1);
}
void _MirrorBinaryTree(Node* root)
{
if (root)
{
swap(root->_left, root->_right);
_MirrorBinaryTree(root->_left);
_MirrorBinaryTree(root->_right);
}
}
void _MirrorBinaryTree_Nor(Node* root)
{
Node* cur = root;
queue<Node*> q;
q.push(cur);
while (!q.empty())
{
cur = q.front();
swap(cur->_left, cur->_right);
q.pop();
if (cur->_left)
q.push(cur->_left);
if (cur->_right)
q.push(cur->_right);
}
}
Node* _Find(Node* root, const T&x)
{
if (root == NULL)
return NULL;
if (root->_data == x)
return root;
Node* ret;
if (ret = _Find(root->_left, x))
return ret;
return _Find(root->_right, x);
}
bool _IsNodeInTree(Node* root, Node* pNode)
{
if (root == NULL)
return NULL;
if (root = pNode)
return root;
Node* ret;
if (ret == _IsNodeInTree(root->_left, pNode))
return ret;
return _IsNodeInTree(root->_right, pNode);
}
bool _IsCompleteBinaryTree(Node* root)
{
queue<Node*> q;
bool flag = true;
q.push(root);
Node* cur = NULL;
while (!q.empty())
{
cur = q.front();
q.pop();
if (cur->_left == NULL)
{
flag = false;
}
else
{
if (flag == false)
{
return false;
}
q.push(cur->_left);
}
if (cur->_right == NULL)
{
flag = false;
}
else
{
if (flag == false)
{
return false;
}
q.push(cur->_right);
}
}
return true;
}
Node* _GetParent(Node* root, Node* pNode)
{
if (root == NULL)
return NULL;
if (root->_left == pNode || root->_right == pNode)
return root;
Node* ret;
if (ret = _GetParent(root->_left, pNode))
return ret;
return _GetParent(root->_right, pNode);
}
Node* _GetLeftChild(Node* root, Node* pNode)
{
if (root == NULL)
return NULL:
if (root == pNode->_left)
return root;
Node* ret;
if (ret = _GetLeftChild(root->_left, pNode))
return ret;
return _GetLeftChild(root->_right, pNode);
}
Node* _GetRightChild(Node* root, Node* pNode)
{
if (root == NULL)
return NULL:
if (root == pNode->_left)
return root;
Node* ret;
if (ret = _GetRightChild(root->_left, pNode))
return ret;
return _GetRightChild(root->_right, pNode);
}
private:
Node* _root;
};
void test()
{
int arr[] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6, '#', '#', 7 };
size_t sz = sizeof(arr) / sizeof(arr[0]);
BinaryTree<int>t(arr, sz, '#');
t.PreveOrder();
t.InOrder();
t.BackOrder();
t.TierOrder();
cout << endl;
BinaryTree<int> ts(t);
t.PreveOrder();
cout << endl;
cout << t.Size() << endl;
cout << t.Leaf() << endl;
cout << t.Depth() << endl;
}
int main()
{
test();
system("pause");
return 0;
}