发自己写的二叉树的抽象数据类型以及相关算法的实现(采用OOP实现的),大家多交流。
类的声明及其相关结构的定义:所有成员函数都通过测试了,大家只要通过CreateBinaryTree()函数用广义表字符串创建广义表后,就可以调用我写的任何一个成员函数了,可能还有其他更多的关于二叉树的算法,正在补充中,大家参考,共同学习共同交流。
呵呵,这也是我写的最长的抽象数据类型的实现了。
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include<iostream.h>
#include<stdlib.h>
#include<string.h>
#include"LinkedStack.h"
#include"LinkedQueue.h"
#include<string.h>
//////////////////////////////////////////////////
//二叉树结点类模板的定义
//////////////////////////////////////////////////
template<class T>
struct BinTreeNode
{
T data; //数据域
BinTreeNode<T>* leftChild; //左子结点地址
BinTreeNode<T>* rightChild; //右子结点地址
BinTreeNode() //构造函数
{
leftChild=NULL;
rightChild=NULL;
};
BinTreeNode(T x,BinTreeNode<T>* l=NULL
,BinTreeNode<T>* r=NULL)
{ //带参数的构造函数
data=x;
leftChild=l;
rightChild=r;
};
};
////////////////////////////////结点类模板定义结束
//////////////////////////////////////////////////
//stkNode结构
//后序非递归遍历中堆栈结点结构的定义
//////////////////////////////////////////////////
template<class T>
struct stkNode
{
//指向树结点的指针
BinTreeNode<T>* ptr;
//该结点所处的左右子树的标志0:左1:右
int tag;
//构造函数
stkNode(BinTreeNode<T>* N=NULL)
:ptr(NULL),tag(1){};
};
///////////////////////////////stkNode结构定义结束
//////////////////////////////////////////////////
//二叉树类模板BinaryTree的声明和定义
//用二叉链表实现二叉树的抽象数据类型
//////////////////////////////////////////////////
template<class T>
class BinaryTree
{
public:
//空构造函数
BinaryTree():root(NULL){};
//带参数的构造函数
BinaryTree(T value):RefValue(value),root(NULL){};
//以描述字符串为参数的构造函数
BinaryTree(char* s,T value);
//复制构造函数
BinaryTree(BinaryTree<T>& bt);
//析构函数
~BinaryTree()
{Destroy(root);
cout<<endl<<"二叉树内存空间释放完毕!"<<endl;};
//判断二叉树是否为空
bool IsEmpty(){return root==NULL;};
//得到当前结点的根结点
BinTreeNode<T>* getRoot()
{return root;};
//得到当前current结点的父结点
BinTreeNode<T>* Parent(BinTreeNode<T>* current)
{return (root==NULL||root==current)?
NULL:Parent(root,current);};
//返回当前结点的左子结点的指针
BinTreeNode<T>* LeftChild(BinTreeNode<T>* current)
{return (current->leftChild==NULL)?
NULL:current->leftChild;};
//返回当前结点的右子结点的指针
BinTreeNode<T>* rightChild(BinTreeNode<T>* current)
{return (current->rightChild==NULL)?
NULL:current->rightChild;};
//返回当前树的高度
int Height()
{return Height(root);};
//返回当前树的总结点数
int Size()
{return Size(root);};
//得到当前二叉树的树根
BinTreeNode<T>* getRoot()const{return root;};
//前序遍历当前二叉树
void preOrder(void(*visit)(BinTreeNode<T>* p))
{cout<<"前序遍历:";preOrder(root,visit);};
//前序遍历的非递归算法1
void preOd1();
//前序遍历的非递归算法2
void preOd2();
//前序遍历的非递归算法3
void preOd3();
//中序遍历当前二叉树
void inOrder(void(*visit)(BinTreeNode<T>* p))
{cout<<"中序遍历:";inOrder(root,visit);};
//中序非递归遍历的算法
void inOd1(void(*visit)(BinTreeNode<T>* p));
//后序遍历当前二叉树
void postOrder(void(*visit)(BinTreeNode<T>* p))
{cout<<"后序遍历:";postOrder(root,visit);};
//后序非递归遍历二叉树的算法实现
void postOd(void(*visit)(BinTreeNode<T>* p));
//按层次顺遍历当前二叉树
void levelOrder(void(*visit)(BinTreeNode<T>* p));
//在二叉树中item元素下,插入新元素item2
bool Insert(const T item1,const T item2,char c);
//在当前的二叉树中搜索值为T的结点,返回该结点的指针
BinTreeNode<T>* Find(T item)const;
//显示二叉树的广义表形式
void PrintBinaryTree()
{PrintBinaryTree(root);};
//判断指定的结点在当前二叉树中是否存在
bool Exist(const T& x)
{return Exist(root,x);};
//利用前序遍历递归创建一棵二叉树
void CreateBinaryTree(istream& in)
{CreateBinaryTree(in,root);};
//通过二叉树的前序序列和中序序列建立一棵二叉树
void CreateByprein(T* pre,T* in,int n);
//统计二叉树中所有结点的个数
int CountNode(){return CountNode(root);};
//交换每个结点的左右子树
void ChangeChild();
//通过数组w[]中的数据元素建立一棵完全二叉树
void CreateComBinTree(T* w,int n);
//在当前的二叉树中寻找值为elem的结点的指针,并显示所有的父结点
BinTreeNode<T>* FindAncestor(T elem)
{return FindAncestor(root,elem);};
//统计子当前二叉树中度为1的结点的个数
int oneDegree()
{return oneDegree(root);};
//统计子当前二叉树中度为1的结点的个数
int towDegree()
{return twoDegree(root);};
//统计子当前二叉树中度为0的结点的个数
int zeroDegree()
{return zeroDegree(root);};
//计算指定结点p在当前二叉树中的深度
int Depth(BinTreeNode<T>* p)
{return Depth(p,root);};
//计算当前二叉树的宽度
int Width();
//删除当前二叉树所有的叶子结点
void deleteLeaf()
{deleteLeaf(root);};
//展出当前二叉树中的最大值
T maxVal()
{return maxVal(root);};
//以前序方式显示当前二叉树中所有结点所在的层次
void preDepth()
{preDepth(root);};
//双序遍历一棵二叉树
void DoubleOrder()
{DoubleOrder(root);};
//前序显示二叉树每个结点及其深度
void PrintDepth()
{PrintDepth(root,1);};
void SearchpreOrder(int k)
{cout<<SearchpreOrder(k,root)->data;};
//判断一棵二叉树是否是完全二叉树
bool IsCompleteBinTree();
//递归:求子二叉树subTree的宽度
void FindWidth(BinTreeNode<T>* subTree
,int* count,int i);
//求当前二叉树的宽度
int FindWidth();
//递归:求解指定结点的子孙的个数
int NumOfSons(BinTreeNode<T>* p);
//调用上面的函数
int NumOfSons()
{return NumOfSons(root);};
//递归:通过前序遍历来统计二叉树中结点总个数
int PreOrderCount(BinTreeNode<T>* subTree);
//调用上面的函数
int PreOrderCount()
{return PreOrderCount(root);};
//递归:通过前序序列来创建一棵二叉树
int PreOrderCreate(char* s,
int start,BinTreeNode<T>*& subTree);
void PreOrderCreate(char* s)
{PreOrderCreate(s,0,root);};
protected:
//二叉树的根结点指针
BinTreeNode<T>* root;
//数据输入停止的标志
T RefValue;
//读入描述字符串建立二叉树
void CreateBinTree(char* BinStr
,BinTreeNode<T>*& subTree);
//用输描述字符串s递归创建一个二叉树
void CreateBinaryTree(istream& in
,BinTreeNode<T>*& subTree);
//删除子树操作
void Destroy(BinTreeNode<T>*& subTree);
//在指定的子树中查找元素x是否存在
bool Exist(BinTreeNode<T>* subTree,const T& x);
//复制操作
BinTreeNode<T>* Copy(BinTreeNode<T>* orignode);
//返回树subTree的高度
int Height(BinTreeNode<T>* subTree);
//返回树的总结点数
int Size(BinTreeNode<T>* subTree);
//返回树subTree中,current结点的父结点
BinTreeNode<T>* Parent(BinTreeNode<T>* subTree
,BinTreeNode<T>* current);
//在子树subTree中搜索值为x的结点的指针
BinTreeNode<T>* Find(BinTreeNode<T>* subTree
,const T& x)const;
//搜索并前序遍历输出
void Traverse(BinTreeNode<T>* subTree
,ostream& out);
//前序遍历
void preOrder(BinTreeNode<T>* subTree
,void(*visit)(BinTreeNode<T>* p));
//中序遍历
void inOrder(BinTreeNode<T>* subTree
,void(*visit)(BinTreeNode<T>* p));
//后序遍历
void postOrder(BinTreeNode<T>* subTree
,void(*visit)(BinTreeNode<T>* p));
//显示二叉树的广义表形式
void PrintBinaryTree(BinTreeNode<T>* subTree);
//通过前序序列和中序序列建立一棵二叉树
BinTreeNode<T>* CreateByprein1(T* pre,T* in,int n);
//统计二叉树subTree子树中所有结点的个数
int CountNode(BinTreeNode<T>* subTree);
//把所有的结点读入到一个数组中
void GetNode(BinTreeNode<T>**);
//找具有指定值Elem的结点的指针,并显示其所有祖先结点
BinTreeNode<T>* FindAncestor(
BinTreeNode<T>* subTree,T elem);
//递归统计子树subTree中度为1的结点的个数
int oneDegree(BinTreeNode<T>* subTree);
//递归统计子树subTree中度为2的结点的个数
int twoDegree(BinTreeNode<T>* subTree);
//递归统计子树subTree中度为0的结点的个数
int zeroDegree(BinTreeNode<T>* subTree);
//计算指定结点p在子树subTree中的深度
int Depth(BinTreeNode<T>* p
,BinTreeNode<T>* subTree);
//递归删除子树subTree里叶子结点
void deleteLeaf(BinTreeNode<T>* subTree);
//递归找出子树subTree中数据最大值
T maxVal(BinTreeNode<T>* subTree);
//以前序的序列显示每个结点所在的层次
void preDepth(BinTreeNode<T>* subTree);
//双序遍历一棵二叉树
void DoubleOrder(BinTreeNode<T>* subTree);
//以前序方式显示每个结点及其深度
void PrintDepth(BinTreeNode<T>* subTree
,int depth);
//递归:得到中序序列中第k个结点的指针
BinTreeNode<T>* SearchpreOrder(int k
,BinTreeNode<T>* subTree);
//递归:给定前序序列,创建所有可能的二叉树
void CtreateBypre(char* s,int begin,int end);
//递归:通过带#的前序序列来创建一棵二叉树
//友元重载>>输入运算符输入二叉树
friend istream& operator>>(istream& in
,BinaryTree<T>& Tree);
//友元重载<<输出运算符输出二叉树
friend ostream& operator<<(ostream& out
,BinaryTree<T>& Tree);
//友元函数,判断两棵二叉树是否相等
friend bool Equal(BinTreeNode<T>* a
,BinTreeNode<T>* b);
//友元函数,判断两棵二叉树是否相等
friend bool BinTreeEqual(BinaryTree<T>& BT1
,BinaryTree<T>& BT2);
//友元重载==运算符
friend bool operator==(BinaryTree<T>& BT1
,BinaryTree<T>& BT2);
};
////////////////////////////////BinaryTree声明结束
[[it] 本帖最后由 geninsf009 于 2008-12-4 22:18 编辑 [/it]]