对一个树的访问,分别可以以前序访问,中序访问,后序访问,层序访问的访问的方法进行访问。
二叉树的表示方法有两种,一种是数组表示法,一种是链式存储法。用数组表示完全二叉树特别有效,但是若用数组表示一般的二叉树就会特别浪费时间,所以一般都会采用链式结构来表示.根据二叉树的定义,可以设计出二叉树的构造,一个二叉树里面应该存有树的根节点(_root),左子树(_lift),右子树(_right)
二叉链表的存储表示
在这里,前序,中序,后序遍历的思想都比较简单,控制好循环条件,用递归方法直接调用就可以,层序遍历的思想是以队列先进先出的思想实现的
![这里写图片描述]
层序遍历思想图(https://img-blog.csdn.net/20170925091220618?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd3luMTI2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
非递归借助栈辅助完成
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
#include<queue>
#include<stack>
using namespace std;
template <class T>
struct NodeBinaryTree
{
NodeBinaryTree(const T& data=T())//定义结构体 并初始化
:_data(data)
, _left(NULL)
, _right(NULL)
{}
NodeBinaryTree* _left;
NodeBinaryTree* _right;
T _data;
};
template <class T>
class BinaryTree
{
typedef NodeBinaryTree<T> Node;
public:
BinaryTree()//无参构造函数
:_root(NULL)
{}
BinaryTree(const T* arr, int sz, const T invalid)//带有参数的构造函数
{
assert(arr);
int index = 0;//代表数组的初始位置
_root = CreatTree(arr, sz, invalid, index);
}
BinaryTree(const BinaryTree<int> & bt)
{
_root = Copy(bt._root);
}
BinaryTree<T> operator=(const BinaryTree<T> &bt) //赋值运算符重载
{
if (this != &bt)
{
Node* tmp = bt._root;
delete[] bt;
_root = tmp;
}
return *this;
}
//BinaryTree<T> operator=(const BinaryTree<T> &bt)//现代写法
//{
// std::swap(_root, bt._root)
// return *this;
//}
~BinaryTree()
{
if (_root)
{
delete[]_root;
_root = NULL;
}
}
//递归思想实现二叉树
void PreOrder()
{
cout << "前序遍历";
_PreOrder(_root);
}
void InOrder()
{
cout << "中序遍历";
_InOrder(_root);
}
void EndOrder()
{
cout << "后序遍历";
_EndOrder(_root);
}
void SeqOrder()
{
cout << "层序遍历";
_SeqOrder(_root);
}
size_t Size()
{
return _Size(_root);
}
size_t Depth()
{
return _Depth(_root);
}
size_t LeafSize()
{
return _LeafSize(_root);
}
size_t GetKLevel_NodeSzie(int k)
{
return _GetKLevel_NodeSzie(_root, k);
}
void Destory()
{
_Destory();
}
protected:
Node* CreatTree(const T*arr,int sz, const T& invalid,int& index)//前序遍历建立二叉树
{
assert(arr);
if ((index <sz) && arr[index] != invalid)
{
Node* _root = new Node(arr[index]);
_root->_left = CreatTree(arr, sz, invalid, ++index);
_root->_right = CreatTree(arr, sz, invalid, ++index);
return _root;
}
return NULL;
}
Node* Copy(Node* _root)
{
Node* tmp = NULL;
if (_root)
{
tmp = new Node(_root->_data);
tmp->_left = Copy(_root->_left);
tmp->_right = Copy(_root->_right );
return tmp;
}
}
void _PreOrder(Node* _root)
{
if (_root)
{
cout << _root->_data<<"->";
_PreOrder(_root->_left);
_PreOrder(_root->_right);
}
}
void _InOrder(Node* _root)
{
if (_root)
{
_InOrder(_root->_left);
cout << _root->_data << "->";
_InOrder(_root->_right);
}
}
void _EndOrder(Node* _root)
{
if (_root)
{
_EndOrder(_root->_left);
_EndOrder(_root->_right);
cout << _root->_data << "->";
}
}
void _SeqOrder(Node* _root)//层序遍历 层序遍历是以队列的思想来实现的(画图)
{
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);
}
}
}
size_t _Size(Node* _root)//不需要定义计数器 浪费空间 直接用递归计算
{
if (_root == NULL)
{
return 0;
}
if (_root)
{
return _Size(_root->_left) + _Size(_root->_right) + 1;
}
}
size_t _Depth(Node* _root)// 左右子树高的+1依次递归
{
if (_root == NULL)
{
return 0;
}
if (_root)
{
return (_Depth(_root->_left) > _Depth(_root->_right)
? _Depth(_root->_left) : _Depth(_root->_right)) + 1;
}
}
size_t _LeafSize( const Node* _root)//返回二叉树中叶子节点的个数 三种情况都要分别考虑到
{
if (_root == NULL)
{
return 0;
}
if ((_root->_left == NULL) && (_root->_right==NULL))
{
return 1;
}
if (_root)
{
return _LeafSize(_root->_left) + _LeafSize(_root->_right);
}
}
size_t _GetKLevel_NodeSzie( Node* _root,int k)//返回第k层节点的个数
{
if (_root == NULL)
{
return 0;
}
if (k==1)
{
return 1;
}
return _GetKLevel_NodeSzie(_root->_left, k - 1)
+ _GetKLevel_NodeSzie(_root->_right, k - 1);
}
public:
//用栈做辅助非递归实现二叉树
void PrevOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
cout << cur->_data << "->";
s.push(cur);
cur = cur->_left;
}
Node*top= s.top();
s.pop();
cur = top->_right;
}
}
void InOrder_NonR()//中序遍历
{
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;
}
}
void EndOrder_NonR()//后续遍历,需要定义一个指向前一个节点的指针
{
Node* cur = _root;
stack<Node*> s;
Node* prev = NULL;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_left;
}
Node* top = s.top();
if (((top->_right) == NULL) ||( top->_right == prev))
{
cout << top->_data<<"->";
s.pop();
prev=top;
}
else
cur = top->_right;
}
}
void _Destory(Node* &_root)
{
if (_root == NULL)
{
return 0;
}
else
{
_Destory(_root->left);
_Destory(_root->right);
delete _root;
_root = NULL;
}
}
protected:
Node* _root;
//
};
void TestBinaryTree()
{
//int arr[10] = { 1, 2, 3, '#', '#', 4, '#', '#', 5, 6 };
int arr[15] = {1,2,'#',3,'#','#',4,5,'#',6,'#',7,'#','#',8};
int sz = sizeof(arr) / sizeof(arr[0]);
//BinaryTree<int> bt;
BinaryTree<int> bt1(arr, sz, '#');
//BinaryTree<int>bt2(bt1);
//BinaryTree<int>bt = bt1;
bt1.PreOrder();
cout << endl;
bt1.InOrder();
cout << endl;
bt1.EndOrder();
cout << endl;
bt1.SeqOrder();
cout << endl;
cout << "Size()? " << bt1.Size() << endl;
cout << "Depth()? " << bt1.Depth()<<endl;
cout << "LeafSize()? " << bt1.LeafSize()<<endl;
cout << "GetKLevel_NodeSzie()? " << bt1.GetKLevel_NodeSzie(3) << endl;
bt1.PrevOrder_NonR();
cout << endl;
bt1.InOrder_NonR();
cout << endl;
bt1.EndOrder_NonR();
cout << endl;
}
int main()
{
TestBinaryTree();
system("pause");
return 0;
}