#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 } }
