二叉树的遍历分为先序遍历,中序遍历,后序遍历,层序遍历;
先序遍历:根节点->左子树->右子树
递归思想:判断根节点是否为空,若不为空则打印根节点数据,然后调用函数取根节点左子树的数据,然后再调用函数取右子树的数据。
递归实现:
void PrevOrder() //前序遍历
{
cout << "前序遍历为:";
_PrevOrder(_root);
cout << endl;
}
void _PrevOrder(Node* root) //根->左子树->右子树
{
if (root == NULL)
return;
cout << root->_value << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
非递归思想:定义一个栈q,定义一个节点p指针指向根节点;将p压入栈后,取该节点的值,并且让p=p的左子树同时压入q栈中,直到左子树为空,这个时候取栈的栈顶元素,然后删除栈顶元素,并将p节点设置为根节点的右子树节点。让其再重复其上述操作。
简单流程图:
非递归实现:
void PrevOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
cout << p->_value << " ";
p = p->_left;
}
Node* node = q.top();
q.pop();
p = node->_right;
}
cout << endl;
}
中序遍历:
递归实现:
void InOrder()//中序遍历
{
cout << "中序遍历为:";
_InOrder(_root);
cout << endl;
}
void _InOrder(Node* root)//左子树->根节点->右子树
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_value << " ";
_InOrder(root->_right);
}
非递归想法: 定义一个栈,定义一个节点p指针指向根节点,然后将这个树的所有左子树压入栈中,然后取其栈顶的元素,然后将栈顶pop掉,让p=栈顶节点的右子树,然后重复上面的步骤。
非递归实现:
void InOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
p = p->_left;
}
Node* node = q.top();
cout << node->_value << " ";
q.pop();
p = node->_right;
}
cout << endl;
}
后序遍历:
递归实现:
void PostOrder()//后序遍历
{
cout << "后序遍历为:";
_PostOrder(_root);
cout << endl;
}
void _PostOrder(Node* root)//左子树->右子树->根节点
{
if (root == NULL)
return;
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_value << " ";
}
非递归实现:定义一个栈,定义一个节点指针p指向树的根节点;再定义一个节点指针prev指向上次所访问的指针,如果栈不为空或者节点p不等于NULL;则将该树的所有左子树压入栈中,然后取栈顶元素,如果这个栈顶元素的右子树为空或者是上次访问的指针,那么说明这个栈顶元素的左右子树已经遍历了,那么就打印该元素节点的数据, 如果这个栈顶元素的右子树不为空或者是不是上次访问的指针,那么就让p指向栈顶元素的右子树,然后重复上述操作。
void PostOrder_NonR()
{
stack<Node*> s;
Node* p = _root;
Node* prev = NULL;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->_left;
}
Node* node = s.top();
if (node->_right == NULL || prev == node->_right)
{
cout <<node->_value << " ";
s.pop();
prev = node;
}
else
{
p = node->_right;
}
}
cout << endl;
}
层序遍历:
void LevelOrder() //层序遍历
{
cout << "层序遍历为:";
if (_root != NULL)
{
queue<Node*> q;
q.push(_root);
while (!q.empty())
{
Node* front = q.front();
cout << front->_value << " ";
q.pop();
if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
cout << endl;
}
size_t Depth() //计算树的深度
{
return _Depth(_root);
}
size_t _Depth(Node* root)
{
if (root == NULL)
return 0;
size_t left = _Depth(root->_left);
size_t right = _Depth(root->_right);
if (left > right)
{
return (left + 1);
}
return (right + 1);
}
计算节点算法:
size_t Size() //统计结点数量
{
return _Size(_root);
}
size_t _Size(Node* root)
{
if (root == NULL)
return 0;
return _Size(root->_left) + _Size(root->_right) + 1;
}
计算叶节点算法:
size_t LeafSize() //统计叶结点的数量
{
return _LeafSize(_root);
}
size_t _LeafSize(Node* root)
{
size_t count = 0;
if (root == NULL)
return 0;
if (root->_left == NULL && root->_right == NULL)
return 1;
else
return _LeafSize(root->_left) + _LeafSize(root->_right);
}
计算满结点算法:
size_t FullSize()//计算满二叉树的结点个数
{
return _FullSize(_root);
}
size_t _FullSize(Node* root)
{
if (root == NULL)
return 0;
else if (root->_left == NULL && root->_right == NULL)
return 0;
else if (root->_left != NULL && root->_right == NULL)
return _FullSize(root->_left);
else if (root->_left == NULL && root->_right != NULL)
return _FullSize(root->_right);
else if (root->_left != NULL && root->_right != NULL)
return _FullSize(root->_left) + _FullSize(root->_right) + 1;
}
寻找节点算法:
Node* Find(const size_t& x)
{
return _Find(_root,x);
}
Node* _Find(Node* root,const size_t& x )
{
if (root == NULL)
reutrn NULL;
if (root->_value == x)
return root;
Node* ret = _Find(root->_left, x);
if (ret != NULL)
return ret;
return _Find(root->_right, x);
}
求K层节点数算法:
size_t GetKleve(size_t K) //获取K层结点个数
{
return _GetKleve(_root, K);
}
size_t _GetKleve(Node* root, size_t K)
{
assert(K > 0);
if (root == NULL)
return 0;
if (K == 1)
return 1;
return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);
}
全部代码实现:
#include<iostream>
using namespace std;
#include<queue>
#include<stack>
#include<assert.h>
template<class T>
struct binarytreeNode
{
T _value;
binarytreeNode<T>* _left; //左子树
binarytreeNode<T>* _right; //右子树
binarytreeNode(const T& value)
:_value(value)
, _left(NULL)
, _right(NULL)
{}
};
template<class T>
class binarytree
{
typedef binarytreeNode<T> Node;
public:
binarytree()
:_root(NULL)
{}
binarytree(T* arr, size_t n, const T& invalid = T())
{
size_t index = 0;
_root = _Greatree(arr, n, invalid, index);
}
~binarytree()
{
_Destory(_root);
}
binarytree(const binarytree<T>& t)
{
_root = Copy(t._root);
}
binarytree<T>& operator=(const binarytree<T>& t)
{
if (this != t)
{
Node* newNode = Copy(t._root);
_Destory(_root);
_root = newNode;
}
return *this;
}
void PrevOrder() //前序遍历
{
cout << "前序遍历为:";
_PrevOrder(_root);
cout << endl;
}
void PrevOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
cout << p->_value << " ";
p = p->_left;
}
Node* node = q.top();
q.pop();
p = node->_right;
}
cout << endl;
}
void InOrder()//中序遍历
{
cout << "中序遍历为:";
_InOrder(_root);
cout << endl;
}
void InOrder_NonR()
{
stack<Node*> q;
Node* p = _root;
while (p != NULL || !q.empty())
{
while (p != NULL)
{
q.push(p);
p = p->_left;
}
Node* node = q.top();
cout << node->_value << " ";
q.pop();
p = node->_right;
}
cout << endl;
}
void PostOrder()//后序遍历
{
cout << "后序遍历为:";
_PostOrder(_root);
cout << endl;
}
void PostOrder_NonR()
{
stack<Node*> s;
Node* p = _root;
Node* prev = NULL;
while (p != NULL || !s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->_left;
}
Node* node = s.top();
if (node->_right == NULL || prev == node->_right)
{
cout <<node->_value << " ";
s.pop();
prev = node;
}
else
{
p = node->_right;
}
}
cout << endl;
}
void LevelOrder() //层序遍历
{
cout << "层序遍历为:";
if (_root != NULL)
{
queue<Node*> q;
q.push(_root);
while (!q.empty())
{
Node* front = q.front();
cout << front->_value << " ";
q.pop();
if (front->_left)
q.push(front->_left);
if (front->_right)
q.push(front->_right);
}
}
cout << endl;
}
size_t Size() //统计结点数量
{
return _Size(_root);
}
size_t Depth() //计算树的深度
{
return _Depth(_root);
}
size_t LeafSize() //统计叶结点的数量
{
return _LeafSize(_root);
}
size_t FullSize()//计算满二叉树的结点个数
{
return _FullSize(_root);
}
size_t GetKleve(size_t K) //获取K层结点个数
{
return _GetKleve(_root, K);
}
Node* Find(const size_t& x)
{
return _Find(_root,x);
}
protected:
void _PrevOrder(Node* root) //根->左子树->右子树
{
if (root == NULL)
return;
cout << root->_value << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
void _InOrder(Node* root)//左子树->根节点->右子树
{
if (root == NULL)
return;
_InOrder(root->_left);
cout << root->_value << " ";
_InOrder(root->_right);
}
void _PostOrder(Node* root)//左子树->右子树->根节点
{
if (root == NULL)
return;
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_value << " ";
}
size_t _Size(Node* root)
{
if (root == NULL)
return 0;
return _Size(root->_left) + _Size(root->_right) + 1;
}
size_t _LeafSize(Node* root)
{
size_t count = 0;
if (root == NULL)
return 0;
if (root->_left == NULL && root->_right == NULL)
return 1;
else
return _LeafSize(root->_left) + _LeafSize(root->_right);
}
size_t _FullSize(Node* root)
{
if (root == NULL)
return 0;
else if (root->_left == NULL && root->_right == NULL)
return 0;
else if (root->_left != NULL && root->_right == NULL)
return _FullSize(root->_left);
else if (root->_left == NULL && root->_right != NULL)
return _FullSize(root->_right);
else if (root->_left != NULL && root->_right != NULL)
return _FullSize(root->_left) + _FullSize(root->_right) + 1;
}
size_t _GetKleve(Node* root, size_t K)
{
assert(K > 0);
if (root == NULL)
return 0;
if (K == 1)
return 1;
return _GetKleve(root->_left, K - 1) + _GetKleve(root->_right, K - 1);
}
size_t _Depth(Node* root)
{
if (root == NULL)
return 0;
size_t left = _Depth(root->_left);
size_t right = _Depth(root->_right);
if (left > right)
{
return (left + 1);
}
return (right + 1);
}
Node* _Find(Node* root,const size_t& x )
{
if (root == NULL)
reutrn NULL;
if (root->_value == x)
return root;
Node* ret = _Find(root->_left, x);
if (ret != NULL)
return ret;
return _Find(root->_right, x);
}
Node* _Greatree(T* arr, size_t n,const T& invalid , size_t& index)
{
Node * node = NULL;
if (arr[index] != invalid && index < n)
{
node = new Node(arr[index]);
node->_left = _Greatree(arr, n, invalid, ++index);
node->_right = _Greatree(arr, n, invalid, ++index);
}
return node;
}
Node* Copy(Node* root)
{
if (root == NULL)
return NULL;
Node* newNode = new Node(root->_value);
newNode->_left = Copy(root->_left);
newNode->_right = Copy(root->_right);
return newNode;
}
void _Destory(Node* root)
{
if (root == NULL)
return;
_Destory(root->_left);
_Destory(root->_right);
delete root;
}
private:
Node* _root;
};
测试用例:
void Text()
{
int array[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
binarytree<int> a(array, sizeof(array) / sizeof(array[0]), '#');
a.PrevOrder();
a.PrevOrder_NonR();
a.InOrder();
a.InOrder_NonR();
a.PostOrder();
a.PostOrder_NonR();
a.LevelOrder();
cout << a.Size() << endl;
cout << a.LeafSize() << endl;
cout << a.Depth() << endl;
cout << a.FullSize() << endl;
cout << a.GetKleve(1) << endl;
cout << a.GetKleve(2) << endl;
cout << a.GetKleve(3) << endl;
binarytree<int> b(a);
}