树:n个有限数据元素的集合
结点:包含了数据和指向其他结点的指针
结点的度:结点拥有的子节点的个数
高度:树当中距根节点最远系欸但的路径长度
前序遍历:根 左子树 右子树
中序遍历:左子树 根 右子树
后序遍历:左子树 右子树 根
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
template<class T>
struct __BinaryNode
{
T _data;
__BinaryNode<T>* _leftChild;
__BinaryNode<T>* _rightChild;
__BinaryNode(const T& x) :_leftChild(NULL), _rightChild(NULL), _data(x)
{}
};
//用一个数组存放数据,然后再构造出一棵二叉树,二叉树没有子树的左右子树用#代替,也就是这里的参数invalid,
//
template<class T>
class BinaryTree
{
typedef __BinaryNode<T> Node;
public:
BinaryTree();
BinaryTree(T* a,size_t n,const T& invalid)
{
size_t index = 0;
_root = _CreatBinaryTree(a,n, invalid,index);
}
//拷贝构造t2(t)
BinaryTree(const BinaryTree<T>& t);
BinaryTree& operator=(const BinaryTree<T>& t);
//析构函数,需要参数,所以写一个函数,里面来调用
~BinaryTree()
{
_Destroy(_root);
_root = NULL;
}
//前序遍历,因为需要传参所以只能再写一个函数
void PrevOrder()
{
_PrevOrder(_root);
cout << endl;
}
//中序遍历
void InOrder()
{
_InOrder(_root);
cout << endl;
}
//后序遍历
void PostOrder()
{
_PostOrder(_root);
cout << endl;
}
//层序遍历,这并不是子问题所以不能使用递归实现,利用队列可以实现
void LevelOrder()
{
queue<Node*> q;
if (_root)
q.push(_root);
while (!q.empty())
{
Node* front = q.front();
cout << front->_data << " ";
q.pop();
if (front->_leftChild != NULL)
q.push(front->_leftChild);
if (front->_rightChild)
q.push(front->_rightChild);
}
cout << endl;
}
//非递归前序遍历 根 + 左 + 右,利用栈来实现结点的遍历
void PrevOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur||!s.empty())
{
while (cur)
{
cout << cur->_data << " ";
s.push(cur);
cur = cur->_leftChild;
}
Node* top = s.top();
s.pop();
cur = top->_rightChild;
}
cout << endl;
}
//非递归中序遍历
void InOrder_NonR()
{
Node* cur = _root;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_leftChild;
}
Node* top = s.top();
cout << top->_data << " ";
s.pop();
cur = top->_rightChild;
}
cout << endl;
}
//非递归后序遍历此处有问题,如何知道右子树已经被访问??定义一个prev去记录并将它去和根的右树比较
void PostOrder_NonR()
{
Node* cur = _root;
Node* prev = NULL;
stack<Node*> s;
while (cur || !s.empty())
{
while (cur)
{
s.push(cur);
cur = cur->_leftChild;
}
Node* top = s.top();
if (top->_rightChild == NULL || prev == top->_rightChild)
{
cout << top->_data << " ";
s.pop();
prev = top;
}
else
{
cur = top->_rightChild;
}
}
cout << endl;
}
//求结点个数,可利用前序遍历,但不同的是多一个参数size,每进行一步就加1
size_t Size()
{
size_t size = 0;
_Size(_root,size);
return size;
}
//先算左树的高度再算右树的高度,然后比较哪个树的高度最高就返回哪个
size_t Depth()
{
return _Depth(_root);
}
size_t LeafSize()
{
size_t size = 0;
_leafNodeSize(_root, size);
return size;
}
//求第k层的结点
size_t GetKLevel()
{
int k = 2;
size_t size = _GetKLevel(_root,k);
return size;
}
private:
//运用递归创建二叉树,当遇到非法值时就退出递归,这样一次创建出左右子树,由于有返回值,所以不能直接使用递归
Node* _CreatBinaryTree(T* a, size_t n, const T& invalid, size_t& index)
{
Node* root = NULL;
if (a[index] != invalid)
{
root = new Node(a[index]);
root->_leftChild = _CreatBinaryTree(a, n, invalid, ++index);
root->_rightChild = _CreatBinaryTree(a, n, invalid, ++index);
}
return root;
}
//二叉树的销毁,因为这是一个二叉树,所以不能直接delete root,需要递归从最后一个节点开始释放
void _Destroy(Node* root)
{
if (root == NULL)
return;
_Destroy(root->_leftChild);
_Destroy(root->_rightChild);
delete root;
}
//前序递归遍历
void _PrevOrder(Node* root)
{
if (root == NULL)
return;
cout << root->_data << " ";
_PrevOrder(root->_leftChild);
_PrevOrder(root->_rightChild);
}
//中序递归遍历
void _InOrder(Node* root)
{
if (root == NULL)
return;
_InOrder(root->_leftChild);
cout << root->_data << " ";
_InOrder(root->_rightChild);
}
//后序遍历
void _PostOrder(Node* root)
{
if (root == NULL)return;
_PostOrder(root->_leftChild);
_PostOrder(root->_rightChild);
cout << root->_data << " ";
}
//求结点的个数,子问题求解
void _Size(Node* root,size_t& n)
{
if (root == NULL)return;
_Size(root->_leftChild, n);
n++;
_Size(root->_rightChild, n);
}
//求二叉树的高度,先算左树的高度再算右树的高度,然后比较哪个树的高度最高就返回哪个
size_t _Depth(Node* root)
{
if (root == NULL) return 0;
size_t left = _Depth(root->_leftChild);
size_t right = _Depth(root->_rightChild);
return left > right ? left + 1 : right + 1;
}
//求叶子节点的个数,叶子节点就是左右子树都为空
void _leafNodeSize(Node* root, size_t& size)
{
if (root == NULL) return;
if (root->_leftChild == NULL&&root->_rightChild == NULL)
{
size++;
}
_leafNodeSize(root->_leftChild, size);
_leafNodeSize(root->_rightChild, size);
}
//求第k层
size_t _GetKLevel(Node* root, size_t k)
{
if (root == NULL) return 0;
if (k == 1)return 1;
return _GetKLevel(root->_leftChild, k - 1) + _GetKLevel(root->_rightChild, k - 1);
}
private:
Node* _root;
};
void testBinaryTree()
{
int array[] = { 1, 2, 3, '#', '#', 4, 7, '#', '#', '#', 5, 6, '#', '#', '#' };
BinaryTree<int> bt(array,sizeof(array)/sizeof(int),'#');
cout << "前序递归遍历 :";
bt.PrevOrder();
cout << "中序递归遍历 :";
bt.InOrder();
cout << "后序递归遍历 :";
bt.PostOrder();
cout << "层序遍历 :";
bt.LevelOrder();
cout << "前序非递归遍历 :";
bt.PrevOrder_NonR();
cout << "中序非递归遍历 :";
bt.InOrder_NonR();
cout << "后序非递归遍历 :";
bt.PostOrder_NonR();
cout << "Size: " << bt.Size() << endl;
cout << "Depth: " << bt.Depth() << endl;
cout << "leafsize: " << bt.LeafSize() << endl;
cout << "GetKLevel :" << bt.GetKLevel() << endl;
}
//测试
#define _CRT_SECURE_NO_WARNINGS 1
#include"BinaryTree.h"
#include<stdlib.h>
int main()
{
testBinaryTree();
system("pause");
return 0;
}
//测试结果: