/************************************************
*
*author:周翔
*e-mail:604487178@qq.com
*blog:http://blog.youkuaiyun.com/zhx6044
*
*
*************************************************/
#include "linkQueue.hpp"
#ifndef BINARYTREE_HPP
#define BINARYTREE_HPP
#include <iostream>
template <typename T>
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
bool isEmpty() const;
void clear();
int size() const;
int height() const;
void create(T stop);
void preTraverse(std::ostream &os = std::cout) const;
void midTraverse(std::ostream &os = std::cout) const;
void postTraverse(std::ostream &os = std::cout) const;
private:
struct node{
T d;
node* lc,*rc;
node():lc(0),rc(0){
}
node(const T &t, node* _lc = 0, node* _rc = 0):
d(t),
lc(_lc),
rc(_rc) {
}
~node(){}
};
node *root;
void clear(node *t) const;
int size(node *t) const;
int height(node *t) const;
void preTraverse(node *t, std::ostream &os = std::cout) const;
void midTraverse(node *t, std::ostream &os = std::cout) const;
void postTraverse(node *t, std::ostream &os = std::cout) const;
};
template <typename T>
BinaryTree<T>::BinaryTree():
root(0)
{
}
template <typename T>
BinaryTree<T>::~BinaryTree()
{
if(!isEmpty()) {
clear();
}
}
template <typename T>
bool BinaryTree<T>::isEmpty() const
{
return root == 0;
}
template <typename T>
void BinaryTree<T>::clear(node *t) const
{
if (t->lc != 0) {
clear(t->lc);
}
if (t->rc != 0) {
clear(t->rc);
}
delete t;
}
template <typename T>
int BinaryTree<T>::size(node *t) const
{
if (t == 0) return 0;
return 1 + size(t->lc) + size(t->rc);
}
template <typename T>
int BinaryTree<T>::height(node *t) const
{
if (t == 0) return 0;
int i = height(t->lc);
int j = height(t->rc);
//高度为来个子树中高度较大的加一
return 1 + ( i > j ? i : j );
}
template <typename T>
void BinaryTree<T>::clear()
{
clear(root);
}
template <typename T>
int BinaryTree<T>::size() const
{
return size(root);
}
template <typename T>
int BinaryTree<T>::height() const
{
return height(root);
}
template <typename T>
void BinaryTree<T>::preTraverse(node *t, std::ostream &os) const
{
if (t != 0) {
os << t->d << " ";
preTraverse(t->lc);
preTraverse(t->rc);
}
}
template <typename T>
void BinaryTree<T>::midTraverse(node *t, std::ostream &os) const
{
if (t != 0) {
midTraverse(t->lc);
os << t->d << " ";
midTraverse(t->rc);
}
}
template <typename T>
void BinaryTree<T>::postTraverse(node *t, std::ostream &os) const
{
if (t != 0) {
postTraverse(t->lc);
postTraverse(t->rc);
os << t->d << " ";
}
}
template <typename T>
void BinaryTree<T>::preTraverse(std::ostream &os) const
{
if (!isEmpty()) {
preTraverse(root,os);
}
}
template <typename T>
void BinaryTree<T>::midTraverse(std::ostream &os) const
{
if (!isEmpty()) {
midTraverse(root,os);
}
}
template <typename T>
void BinaryTree<T>::postTraverse(std::ostream &os) const
{
if (!isEmpty()) {
postTraverse(root,os);
}
}
template <typename T>
/**
* @brief BinaryTree<T>::create 从上到下按层创建
* @param stop 结束符
*/
void BinaryTree<T>::create(T stop)
{
LinkQueue<node*> queue;
T x,l,r;
node* t;
std::cout << "输入根节点:\n";
std::cin >> x;
root = new node(x);
queue.enqueue(root);
while (!queue.isEmpty()) {
t = queue.dequeue();
std::cout << "输入" << "节点" << t->d << "的两个孩子,没有则输入" << stop << '\n';
std::cin >> l >> r;
if (l != stop) queue.enqueue(t->lc = new node(l));
if (r != stop) queue.enqueue(t->rc = new node(r));
}
}
#endif // BINARYTREE_HPP
之后撸的加上
template <typename T>
void BinaryTree<T>::preTraverse2(std::ostream &os) const
{
if (isEmpty()) {
os << "这是一颗空树!\n";
} else {
LinkStack<node*> stack;
stack.push(root);
while(!stack.isEmpty()) {
node *t = stack.pop();
os << t->d << " ";
//先压右子树再压左子树,这样左子树在上可以先遍历
if (t->rc != 0) stack.push(t->rc);
if (t->lc != 0) stack.push(t->lc);
}
}
}
template <typename T>
/**
* @brief BinaryTree<T>::midTraverse2
* @param os
*
*
*
* 根节点第一次出栈,然后进栈,左子树进栈,然后遍历左子树,根节点第二次出栈,右子树进栈
*
*/
void BinaryTree<T>::midTraverse2(std::ostream &os) const
{
if (isEmpty()) {
os << "这是一颗空树!\n";
} else {
LinkStack<elemt> stack;
stack.push(elemt(root));
while(!stack.isEmpty()) {
elemt t = stack.pop();
if (++t.step == 2) {
os << t.n->d << " ";
if (t.n->rc != 0) {
stack.push(elemt(t.n->rc));
}
} else {
stack.push(t);
if(t.n->lc != 0) {
stack.push(t.n->lc);
}
}
}
}
}
template <typename T>
/**
* @brief BinaryTree<T>::postTraverse2
* @param os
*
*
*
* 根节点第一次出栈进栈,左子树进栈,第二次进栈出栈,右子树进栈,第三次出栈
*/
void BinaryTree<T>::postTraverse2(std::ostream &os) const
{
if (isEmpty()) {
os << "这是一颗空树!\n";
} else {
LinkStack<elemt> stack;
stack.push(elemt(root));
while(!stack.isEmpty()) {
elemt t = stack.pop();
if (++t.step == 3) {
os << t.n->d << " ";
} else {
if (t.step == 2) {
stack.push(t);
if(t.n->rc != 0) {
stack.push(t.n->rc);
}
} else {
stack.push(t);
if(t.n->lc != 0) {
stack.push(t.n->lc);
}
}
}
}
}
}
template <typename T>
/**
* @brief BinaryTree<T>::changeChildrens 交换子节点,使用一个队列完成
*/
void BinaryTree<T>::changeChildrens()
{
LinkQueue<node*> queue;
queue.enqueue(root);
while(!queue.isEmpty()) {
node *t = queue.dequeue();
if (t != NULL) {
queue.enqueue(t->lc);
queue.enqueue(t->rc);//将两个字节点入队
node *t2 = t->lc;//交换子节点
t->lc = t->rc;
t->rc = t2;
}
}
}
template <typename T>
void BinaryTree<T>::levelTraverse(std::ostream &os) const
{
LinkQueue<node*> queue;
queue.enqueue(root);
while(!queue.isEmpty()) {
node *t = queue.dequeue();
if (t != NULL) {
os << t->d << " ";
queue.enqueue(t->lc);
queue.enqueue(t->rc);
}
}
}
template <typename T>
int BinaryTree<T>::degreeTwo() const
{
int re = 0;
if (isEmpty()) {
} else {
LinkQueue<node*> queue;
queue.enqueue(root);
while(!queue.isEmpty()) {
node *t = queue.dequeue();
if (t->lc != NULL) {
queue.enqueue(t->lc);
if (t->rc != NULL) {
queue.enqueue(t->rc);
++re;
}
} else {
if (t->rc != NULL) {
queue.enqueue(t->rc);
}
}
}
}
return re;
}
template <typename T>
/**
* @brief BinaryTree<T>::completeBT 将树作为完全二叉树考虑构件,最后看结论是否矛盾(反证法)
* @return
*/
bool BinaryTree<T>::completeBT() const
{
LinkQueue<elemt> queue;
elemt t,tc;
int c = 1;//节点的个数
int l = 1;//最后节点编号
//root编号为1,根据性质5,如果是完全二叉树则节点个数等于最后节点的编号
if (isEmpty()) return true;//空树是完全二叉树
t.n = root;
t.step = 1;
queue.enqueue(t);
while (!queue.isEmpty()) {
t = queue.dequeue();
if (t.n->lc != NULL) {
++c;
tc.n = t.n->lc;
l = tc.step = t.step * 2;//完全二叉树性质5
queue.enqueue(tc);
}
if (t.n->rc != NULL) {
++c;
tc.n = t.n->rc;
l = tc.step = t.step * 2 + 1;
queue.enqueue(tc);
}
}
return c == l;
}
template <typename T>
/**
* @brief BinaryTree<T>::isEqual
* @param t1
* @param t2
* @return
*
*
*写递归主要是找出递归出口,这个有三个出口,值不同和形状不同,和都是空节点
*/
bool BinaryTree<T>::isEqual(BinaryTree::node *t1, BinaryTree::node *t2)
{
//形状,值相同,最后如果相同是以形状出口
if (t1 == NULL && t2 == NULL) return true;
if (t1 == NULL || t2 == NULL) return false;
//值不同,直接出口
if (t1->d != t2->d) return false;
//值相同,再看形状,可以是值出口和形状出口
return isEqual(t1->lc, t2->lc) && isEqual(t1->rc, t2->rc);
}
template <typename T>
bool operator == (const BinaryTree<T> &bt1, const BinaryTree<T> &bt2)
{
return BinaryTree<T>::isEqual(bt1.root,bt2.root);
}
template <typename T>
/**
* @brief BinaryTree<T>::mirror 树是镜像的吗,左右子树对称
* @return
*/
bool BinaryTree<T>::mirror() const
{
if (isEmpty()) return false;
return isMirror(root->lc,root->rc);
}
template <typename T>
bool BinaryTree<T>::isMirror(BinaryTree::node *t1, BinaryTree::node *t2)
{
if (t1 == NULL && t2 == NULL) return true;
if (t1 == NULL || t2 == NULL) return false;
if (t1->d != t2->d) return false;
return isMirror(t1->lc, t2->rc) && isMirror(t1->rc, t2->lc);
}