1.实现二叉树的前/中/后序的递归和非递归的的遍历,以及层序遍历。
2.实现二叉树的各种应用。
① 二叉树中的所有结点 ② 二叉树中所有叶子节点个数 ③ 二叉树的深度(高度) ④ 二叉树中第K层的结点个数
以下是代码的具体实现
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
template <class T>
struct Tree_Node
{
T _data;
Tree_Node* _left;
Tree_Node* _right;
Tree_Node(const T& val)
:_data(val)
, _left(NULL)
, _right(NULL)
{}
};
template<class T>
class Binary_Tree
{
public:
typedef Tree_Node<T> Node;
Binary_Tree(const int Tree[] ,int& Index ,const int Invalid_value = '*') //
{
//这块要自己定义一个初始化函数,因为构造函数没有返回值,
//使用递归的话要使用返回值
//下边有两种初始化方法,都行,但是二叉树的数组要初始化好,不然就蹦了
//这个是递归 有返回值接收的
//_root = Init(_root, Tree, Index, Invalid_value);
//这个事不需要返回值接收的,传值是【引用】
Init(_root, Tree, Index, Invalid_value);
}
//二叉树的初始化,用递归就可以初始化
//如果不是传返回值的,就要使用【引用】,不然传参过来的只是零时变量,不会改变root的值
void Init(Node*& root, const int Tree[], int& Index, const int& Invalid_value)
{
if(Tree[Index] == Invalid_value)
{
Index++;
} // 1, 2,'*', 3,'*',8 ,'*','*'
else
{
root = new Node(Tree[Index]);
Index++;
Init(root->_left, Tree, Index, Invalid_value);
Init(root->_right, Tree, Index, Invalid_value);
}
}
//Node* Init(Node* root, const int Tree[], int& Index, const int& Invalid_value)
//{
// if (Tree[Index] == Invalid_value)
// {
// Index++;
// } // 1, 2,'*', 3,'*',8 ,'*','*'
// else
// {
// root = new Node(Tree[Index]);
// Index++;
// root->_left = Init(root->_left, Tree, Index, Invalid_value);
// root->_right = Init(root->_right, Tree, Index, Invalid_value);
// }
// return root;
//}
//拷贝构造
//BinaryTree(const BinaryTree& t)
//{}
//BinaryTree& operator=(const BinaryTree& t);
//~BinaryTree();
//前序-------递归
void PrevOrder()
{
// 头 左 右
_PrevOrder(_root);
}
//中序------递归
void InOrder()
{
_InOrder(_root);
}
//后序------递归
void PostOrder()
{
_PostOrder(_root);
}
//层序访问二叉树(从上到下,从左到右)
//使用队列实现
void LevelOrder()
{
queue<Node*> q;
_LevelOrder(_root,q);
}
//前序----非递归----使用栈
void PrevOrder_NonR()
{
//创建一个栈,用来存储左子树的头结点
stack<Node*> s;
_PrevOrder_NonR(_root,s);
}
//中序----非递归
void InOrder_NonR()
{
stack<Node*> s;
_InOrder_NonR(_root,s);
}
//后序----非递归
void PostOrder_NonR()
{
stack<Node*> s;
_PostOrder_NonR(_root, s);
}
//二叉树中所有结点个数
size_t Size()
{
return _Size(_root);
}
//二叉树的深度
size_t Depth()
{
return _Depth(_root);
}
//叶子(最底层)结点个数--递归
size_t Leaf_Size()
{
return _Leaf_Size(_root);
}
//第K层的结点个数
size_t GetKLevel(size_t K)
{
return _GetKLevel(_root,K);
}
protected:
//上面的前序输出只是对外的一个接口,这里是实现函数,不对外开放,因此要protected
//前序---递归
void _PrevOrder(Node* root)
{
if (root)
{
cout << root->_data << " ";
_PrevOrder(root->_left);
_PrevOrder(root->_right);
}
}
//中序---递归
void _InOrder(Node* root)
{
if (root)
{
_InOrder(root->_left);
cout << root->_data << " ";
_InOrder(root->_right);
}
}
//后序---递归
void _PostOrder(Node* root)
{
if (root)
{
_PostOrder(root->_left);
_PostOrder(root->_right);
cout << root->_data << " ";
}
}
//前序非递归
void _PrevOrder_NonR(Node* root,stack<Node*> s)
{
Node* tmp = root;
while (!s.empty() || tmp)
{
while (tmp != NULL)
{
s.push(tmp);
cout << tmp->_data << " ";
tmp = tmp->_left;
}
tmp = s.top();
s.pop();
//子问题
tmp = tmp->_right;
}
}
//中序----非递归
void _InOrder_NonR(Node* _root,stack<Node*> s)
{
Node* root = _root;
while (!s.empty() || root)
{
//遍历左子树
while (root != NULL)
{
s.push(root);
root = root->_left;
}
//每次先输出左结点
cout << s.top()->_data << " ";
root = s.top();
s.pop();
//子问题
root = root->_right;
}
}
//后序---非递归
void _PostOrder_NonR(Node* _root,stack<Node*> s)
{
Node* prev = NULL; //用 prev 来存储上一个结点的位置,如果prev == 当前结点的右子树,那就说明已经遍历过右子树
Node* root = _root;
while (!s.empty() || root)
{
while (root)
{
s.push(root);
root = root->_left;
}
root = s.top();
//这里用一个标志 prev 来判断是否已经走过右子树,如果当前结点的右子树的地址等于 prev,那就说明
//已经走过右子树,不能再遍历右子树;
if (root->_right == NULL || root->_right== prev)
{
prev = root;
cout << root->_data << " ";
s.pop();
root = NULL; //输出后,置为空,这个结点的子树就已经结束,以便访问上一个结点的右结点
}
else
{
root = root->_right;
}
}
}
//叶子(最底层)结点个数--递归
size_t _Leaf_Size(Node* root)
{
if (root == NULL)
{
return 0;
}
else if (root->_left == NULL && root->_right == NULL)
{
return 1;
}
else
{
return _Leaf_Size(root->_left) + _Leaf_Size(root->_right);
}
}
//结点个数(所有结点个数)
size_t _Size(Node* root)
{
if (root == NULL)
{
return 0;
}
else
{ //当前结点个数(1) + 子树的结点个数
return 1 + _Size(root->_left) + _Size(root->_right);
}
}
// 二叉树的深度(高度)
size_t _Depth(Node* root)
{
int left_hight = 0;
int right_hight = 0;
if (root == 0)
{
return 0;
}
left_hight = _Depth(root->_left);
right_hight = _Depth(root->_right);
return left_hight > right_hight ? left_hight + 1 : right_hight + 1;
}
//第K层结点个数
size_t _GetKLevel(Node* root, size_t K)
{
//默认二叉树根节点从一层开始,所以0层是0个结点
if (K == 0 || root == NULL) //这里不仅要判断k == 0 时返回0,还要判断root == NULL,也是返回0;
{
return 0;
}
else if (K == 1)
{
return 1;
}
K--;
return _GetKLevel(root->_left,K) + _GetKLevel(root->_right,K);
}
层序访问二叉树(从上到下,从左到右)
//使用队列实现
void _LevelOrder(Node* Root, queue<Node*> q)
{
if (Root == NULL)
{
return;
}
Node* root = Root;
q.push(root);
//这里要用q.front()函数来判断二叉树是否已经遍历完成
while (q.front())
{
Node* Front = q.front();
q.pop();
cout << Front->_data << " ";
q.push(Front->_left);
q.push(Front->_right);
}
}
private:
Node* _root;
};
void test1()
{
int Tree[] = { 1, 2, 4, '*','*',5 ,'*','*',3 ,6,'*','*',7,'*','*','*'};
//初始化要初始化完全,不然奔溃
//int Tree[] = { '*' };
int Index = 0;
int Invalid_value = '*';
Binary_Tree<int> tree(Tree,Index,Invalid_value);
//tree.PrevOrder();
//cout << endl;
//tree.InOrder();
tree.PostOrder();
cout << endl;
//tree.PostOrder();
//tree.PrevOrder_NonR();
//tree.InOrder_NonR();
tree.PostOrder_NonR();
cout << endl;
cout << tree.Leaf_Size() << " ";
cout << endl;
cout << tree.Size() << " ";
cout << endl;
cout << tree.Depth() << " ";
cout << endl;
cout << tree.GetKLevel(1) << " ";
cout << endl;
tree.LevelOrder();
}