#pragma once #include "stdafx.h" #include "BinTreeNode.h" #include "Stack.h" //二叉树类BinTree的声明 template <typename T> class BinTree { private: //指向根结点 BinTreeNode<T>* root; //输入stop时,终止结点的输入 T stop; //从结点begin开始搜索,返回结点current的父结点 BinTreeNode<T>* father(BinTreeNode<T>* begin, BinTreeNode<T>* current); //10个方法 public: //Constructor(),构造函数--在声明一棵二叉树时进行初始化,生成一棵空树 BinTree() :root(NULL) {} //Constructor(),//输入stop时,终止结点的输入 BinTree(T mark) :root(NULL), stop(mark) {} //DeConstructor(),析构函数--删除整棵二叉树 virtual ~BinTree() { DelSubtree root; } //在当前结点的位置插入一个结点 int Insert(BinTreeNode<T>*& current, const T& item); //从结点current开始,搜索数据值为item的结点,返回编号 int Find(BinTreeNode<T>*& current, const T& item) const; //删除结点current及其左右子树 void DelSubtree(BinTreeNode<T>* current); //先根遍历并输出以结点t为根的树 void Preorder(BinTreeNode<T>* t, ostrem& out)const; //中根遍历并输出以结点t为根的树 void Inorder(BinTreeNode<T>* t, ostrem& out)const; //后根遍历并输出以结点t为根的树 void Postorder(BinTreeNode<T>* t, ostrem& out)const; //判断二叉树是否为空 virtual int IsEmpty() { return root == NULL ? 1 : 0; } //计算结点个数,二叉树遍历的应用, void countleaf(BinTreeNode<T>* t, int& count) { if (t != NULL) { if ((t->left == NULL) && (t->right == NULL)) count++; countleaf(t->left, count); countleaf(t->right, count); } } //交换二叉树中每个结点的左子女和右子女,先序可,后序可,中序不可 void exchange(BinTreeNode<T>* t) { BinTreeNode<T>* temp; if ((t->left != NULL) || (t->right != NULL)) { temp = t->left; t->left = t->right; t->right = temp; exchange(t->left); exchange(t->right); } } //删除结点current极其左右子树,后序可 void DelSubtree(BinTreeNode<T>* current) { if (current != NULL) { DelSubtree(current->left); DelSubtree(current->right); delete current; } } //按先序顺序构造一棵二叉树 void CreateBiTree(BiTree<T>& T); //先序遍历二叉树的递归算法1 bool PreOrderTraverse(BinTreeNode<T>* T, bool(*Visit)(T e)) { if (T != NULL) { Visit(T->data); PreOrderTraverse(T->left, Visit(T->data)); PreOrderTraverse(T->right, Visit(T->data)); return ERROR; } else return true; } //中根遍历并输出以结点t为根的树,非递归算法,自建栈 bool InOrderTrverse(BinTreeNode<T>* T, bool(*Visit)(T e)) { BinTreeNode<T>* p = T; //临时指针 Stack<T> S = new Stack<T>(); //非递归算法,自建栈,利用栈的特性来实现手动递归 while (p != NULL || !S.IsEmpty()) { if (p != NULL) { //根结点入栈,遍历左子树 push(S, p); p = p->left; } else { //根结点出栈,访问根结点,遍历右子树 pop(S, p); Visit(p->data); p = p->right; }//else }//while return true; } //后根遍历并输出以结点t为根的树,非递归算法,自建栈 bool PostOrderTrverse(BinTreeNode<T>* T, bool(*Visit)(T)) { BinTreeNode<T>* p = T; //临时指针 Stack<T> S = new Stack<T>(); //非递归算法,自建栈,利用栈的特性来实现手动递归 while (p != NULL || !S.IsEmpty()) { if (p != NULL) { //根结点入栈,遍历左子树 push(S, p); p = p->left; } else { //根结点出栈,访问根结点,遍历右子树 pop(S, p); p = p->right; Visit(p->data); }//else }//while return true; } //层次遍历二叉树 bool LevelOrderTraverse(BinTreeNode<T>* T, bool(*Visit)(T)); //访问结点 bool Visit(T e) { if (!e) { return false; } //cout << t->data); PrintElement(T e); return true; } //输出结点 bool PrintElement(T e) { printf(e); return true; } };//!_class BinTree //先根遍历并输出以结点t为根的树,递归算法 template<typename T> inline void BinTree<T>::Preorder(BinTreeNode<T>* t, ostrem & out) const { if (t != NULL) { cout << t->data); //visit() root node Preorder(t->left, out); //enter left subtree Preorder(t->right, out); //enter right subtree } } //中根遍历并输出以结点t为根的树,const表示这个是访问函数,不能修改结点,递归算法 template<typename T> inline void BinTree<T>::Inorder(BinTreeNode<T>* t, ostrem & out) const { if (t != NULL) { Inorder(t->left, out); //enter left subtree cout << t->data); //visit() root node Inorder(t->right, out); //enter right subtree } } //后根遍历并输出以结点t为根的树,递归算法 template<typename T> inline void BinTree<T>::Postorder(BinTreeNode<T>* t, ostrem & out) const { if (t != NULL) { Postorder(t->left, out); //enter left subtree Postorder(t->right, out); //enter right subtree cout << t->data); //visit() root node } }