二叉树应用-二叉搜索树类模板的实现(数据结构基础 第6周)

来源:互联网 发布:淘宝商城女装裙子 编辑:程序博客网 时间:2024/05/18 12:43

这里简单实现了二叉搜索树类模板,程序中二叉搜索树继承于二叉树。
该程序仅使用了题目http://dsalgo.openjudge.cn/201409week6/2 进行了简单测试。
源码
//test.cpp

#include <iostream>#include "BinarySearchTree.h"using namespace std;int main() {    BinarySearchTree<int> bst;    int i;    while(cin>>i) {        BinaryTreeNode<int> *newpointer=new BinaryTreeNode<int>(i);        bst.InsertNode(newpointer);    }    vector<int> v;    v=bst.traversePreOrder();    for (int i=0; i<v.size(); i++) {        cout << v.at(i) << ' ';    }    return 0;}

//BinaryTreeNode.h

#pragma oncetemplate <class T> class BinaryTree;template <class T> class BinarySearchTree;template <class T>class BinaryTreeNode  {friend class BinaryTree<T>;friend class BinarySearchTree<T>;private:    T  element;                                         //二叉树结点数据域    BinaryTreeNode<T>*  left;                           //二叉树结点指向左子树的指针    BinaryTreeNode<T>*  right;                          //二叉树结点指向左子树的指针public:    BinaryTreeNode();    BinaryTreeNode(const T& ele);                       //给定数据的构造函数    BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r);//给定数据的左右指针的构造函数    T  value() const;                                   //返回当前结点的数据    BinaryTreeNode<T>& operator= (const BinaryTreeNode<T>& Node)    {this=Node;};                                       //重载赋值操作符    BinaryTreeNode<T>*  leftchild() const;              //返回当前结点指向左子树的指针    BinaryTreeNode<T>*  rightchild() const;             //返回当前结点指向右子树的指针    void  setLeftchild(BinaryTreeNode<T>*);             //设置当前结点的左子树    void  setRightchild(BinaryTreeNode<T>*);            //设置当前结点的右子树    void  setValue(const T& val);                       //设置当前结点的数据域    bool  isLeaf() const;                               //判定当前结点是否为叶结点,若是返回true};template<class T>BinaryTreeNode<T>::BinaryTreeNode(){    left=right=NULL;}template<class T>BinaryTreeNode<T>::BinaryTreeNode(const T& ele) //给定数据的构造函数{    element=ele;    left=right=NULL;}template<class T>BinaryTreeNode<T>::BinaryTreeNode(const T& ele,BinaryTreeNode* l, BinaryTreeNode* r)    //给定数据的左右指针的构造函数{    element=ele;    left=l;    right=r;}template<class T>T  BinaryTreeNode<T>::value() const{    return element; }template<class T>BinaryTreeNode<T>*  BinaryTreeNode<T>::leftchild() const{    return left;                                //返回当前结点指向左子树的指针}template<class T>BinaryTreeNode<T>*  BinaryTreeNode<T>::rightchild() const{    return right;                               //返回当前结点指向右子树的指针}   template<class T>void  BinaryTreeNode<T>::setLeftchild(BinaryTreeNode<T>* subroot)//设置当前结点的左子树{    left=subroot;}template<class T>void  BinaryTreeNode<T>::setRightchild(BinaryTreeNode<T>* subroot)//设置当前结点的右子树{    right=subroot;}template<class T>void  BinaryTreeNode<T>::setValue(const T& val) //设置当前结点的数据域{    element = val; } template<class T>bool  BinaryTreeNode<T>::isLeaf() const         //判定当前结点是否为叶结点,若是返回true{    return (left == NULL) && (right == NULL); }

//BinaryTree.h

#pragma once#include "BinaryTreeNode.h"#include <stack>#include <queue>#include <vector>using namespace std;enum Tags{Left,Right};template <class T>class StackElement{public:    BinaryTreeNode<T>* pointer;    Tags tag;};template <class T>class BinaryTree  {protected:    BinaryTreeNode<T>*  root;                               //二叉树根结点指针    vector<T> elements;  //用于保存遍历的元素private:    void Visit(T elem) {elements.push_back(elem);};  //遍历访问元素的值    void PreOrder(BinaryTreeNode<T>* root); //从root前序遍历二叉树或其子树(递归部分)    void InOrder(BinaryTreeNode<T>* root);  //从root中序遍历二叉树或其子树(递归部分)        void PostOrder(BinaryTreeNode<T>* root); //从root后序遍历二叉树或其子树(递归部分)       void PreOrderWithoutRecusion(BinaryTreeNode<T>* root); //从root非递归前序遍历二叉树或其子树(递归部分)      void InOrderWithoutRecusion(BinaryTreeNode<T>* root);  //从root非递归中序遍历二叉树或其子树(递归部分)      void PostOrderWithoutRecusion(BinaryTreeNode<T>* root);  //从root非递归后序遍历二叉树或其子树  (递归部分)    void PostOrderWithoutRecusion2(BinaryTreeNode<T>* root);  //从root非递归后序遍历二叉树或其子树, 另一个版本(递归部分)    void LevelOrder(BinaryTreeNode<T>* root);  //按层次遍历二叉树或其子树protected:    BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>* root,BinaryTreeNode<T>* current);//递归由root结点查找current结点的父结点public:    BinaryTree(){root=NULL;};                               //构造函数    virtual ~BinaryTree(){DeleteBinaryTree(root);};            //析构函数    bool isEmpty() const                                {return ((root)?TRUE:FALSE);};                          //判定二叉树是否为空树    void Initialize(BinaryTreeNode<T>* pointer) {root=pointer;};        BinaryTreeNode<T>* Root() {return root;};  //返回二叉树根节点    BinaryTreeNode<T>* Parent(BinaryTreeNode<T>* current); //返回current结点的父结点指针      BinaryTreeNode<T>* LeftSibling(BinaryTreeNode<T>* current); //返回current结点的左兄弟       BinaryTreeNode<T>* RightSibling(BinaryTreeNode<T>* current);//返回current结点的右兄弟    //以elem作为根结点,leftTree作为树的左子树,rightTree作为树的右子树,构造一棵新的二叉树    void CreateTree(const T& elem, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree);      void DeleteBinaryTree(BinaryTreeNode<T>* root);     //递归删除二叉树或其子树       vector<T> traversePreOrder();  //从根节点前序遍历,以下依次对应    vector<T> traverseInOrder();    vector<T> traversePostOrder();    vector<T> traversePreOrderWithoutRecusion();    vector<T> traverseInOrderWithoutRecusion();    vector<T> traversePostOrderWithoutRecusion();    vector<T> traversePostOrderWithoutRecusion2();    vector<T> traverseLevelOrder();     };template<class T>BinaryTreeNode<T>* BinaryTree<T>::GetParent(BinaryTreeNode<T>* root,BinaryTreeNode<T>* current){    //从二叉树的root结点开始,查找current结点的父结点    BinaryTreeNode<T>* temp;    if(root==NULL)        return NULL;    //找到父结点    if((root->leftchild()==current)||(root->rightchild()==current))        return root;    //递归寻找父结点    if((temp=GetParent(root->leftchild(),current))!=NULL)        return temp;    else return GetParent(root->rightchild(),current);  }template<class T>BinaryTreeNode<T>* BinaryTree<T>::Parent(BinaryTreeNode<T>* current)  //返回current结点的父结点指针{    if((current==NULL)||(current==root))        return NULL;                    //空结点或者current为根结点时,返回NULL    return GetParent(root,current);     //调用递归函数寻找父结点}template<class T>BinaryTreeNode<T>* BinaryTree<T>::LeftSibling(BinaryTreeNode<T>* current)  //返回current结点的左兄弟{    if(current)                                         //current不为空    {        BinaryTreeNode<T>* temp=Parent(current);    //返回current结点的父结点        if((temp==NULL)||current==temp->leftchild())            return  NULL;           //如果父结点为空,或者current没有左兄弟        else return temp->leftchild();    }    return NULL;}template<class T>BinaryTreeNode<T>* BinaryTree<T>::RightSibling(BinaryTreeNode<T>* current) //返回current结点的右兄弟{    if(current)                                 //current不为空    {        BinaryTreeNode<T>* temp=Parent(current);//返回current结点的父结点        if((temp==NULL)||current==temp->rightchild())            return  NULL;                   //如果父结点为空,或者current没有右兄弟        else return temp->rightchild();    }    return NULL;}template<class T>void BinaryTree<T>::CreateTree(const T& elem, BinaryTree<T>& leftTree, BinaryTree<T>& rightTree) //以elem作为根结点,leftTree作为树的左子树,rightTree作为树的右子树,构造一棵新的二叉树{    root=new BinaryTreeNode<T>(elem,leftTree.root,rightTree.root);  //创建新树    leftTree.root=rightTree.root=NULL;                              //原来两棵子树的根结点指空,避免访问}template<class T>void BinaryTree<T>::DeleteBinaryTree(BinaryTreeNode<T>* root)       //递归删除二叉树或其子树{    if(root)    {        DeleteBinaryTree(root->left);        DeleteBinaryTree(root->right);        delete root;    };};template<class T>void BinaryTree<T>::PreOrder(BinaryTreeNode<T>* root)               //前序遍历二叉树或其子树{    if(root!=NULL)    {        Visit(root->value());           PreOrder(root->leftchild());            //访问左子树        PreOrder(root->rightchild());           //访问右子树    }};template<class T>vector<T> BinaryTree<T>::traversePreOrder() {    elements.clear();    PreOrder(root);    return elements;}template<class T>void BinaryTree<T>::InOrder(BinaryTreeNode<T>* root)                //中序遍历二叉树或其子树{    if(root!=NULL)    {        InOrder (root->leftchild());            //访问左子树        Visit(root->value());           //访问当前结点        InOrder (root->rightchild());           //访问右子树    }}template<class T>vector<T> BinaryTree<T>::traverseInOrder() {    elements.clear();    InOrder(root);    return elements;}template<class T>void BinaryTree<T>::PostOrder(BinaryTreeNode<T>* root)              //后序遍历二叉树或其子树{    if(root!=NULL)    {        PostOrder(root->leftchild());           //访问左子树        PostOrder (root->rightchild());         //访问右子树        Visit(root->value());           //访问当前结点    }}template<class T>vector<T> BinaryTree<T>::traversePostOrder() {    elements.clear();    PostOrder(root);    return elements;}template<class T>void BinaryTree<T>::PreOrderWithoutRecusion(BinaryTreeNode<T>* root)//非递归前序遍历二叉树或其子树{//  using std::stack;    stack<BinaryTreeNode<T>* > aStack;    BinaryTreeNode<T>* pointer=root;                //保存输入参数        while(!aStack.empty()||pointer)                 {        if(pointer){            Visit(pointer->value());        //访问当前结点            aStack.push(pointer);                   //当前结点地址入栈            pointer=pointer->leftchild();           //当前链接结构指向左孩子        }        else {                                          //左子树访问完毕,转向访问右子树            pointer=aStack.top();                   //栈顶元素退栈                             aStack.pop();            pointer=pointer->rightchild();      //当前链接结构指向右孩子        } //else    } //while}template<class T>vector<T> BinaryTree<T>::traversePreOrderWithoutRecusion() {    elements.clear();    PreOrderWithoutRecusion(root);    return elements;}template<class T>void BinaryTree<T>::InOrderWithoutRecusion(BinaryTreeNode<T>* root) //非递归中序遍历二叉树或其子树{//  using std::stack;    stack<BinaryTreeNode<T>* > aStack;    BinaryTreeNode<T>* pointer=root;                //保存输入参数        while(!aStack.empty()||pointer)                 {        if(pointer){            aStack.push(pointer);                   //当前结点地址入栈            pointer=pointer->leftchild();           //当前链接结构指向左孩子        }        else {                                          //左子树访问完毕,转向访问右子树            pointer=aStack.top();                           Visit(pointer->value());        //访问当前结点            pointer=pointer->rightchild();      //当前链接结构指向右孩子            aStack.pop();                           //栈顶元素退栈                         } //else    } //while}template<class T>vector<T> BinaryTree<T>::traverseInOrderWithoutRecusion() {    elements.clear();    InOrderWithoutRecusion(root);    return elements;}template<class T>void BinaryTree<T>::PostOrderWithoutRecusion(BinaryTreeNode<T>* root)//非递归后序遍历二叉树或其子树{//  using std::stack;    StackElement<T> element;    stack<StackElement<T > > aStack;    BinaryTreeNode<T>* pointer;    if(NULL==root)        return;                                     //空树即返回    else pointer=root;    while(true)    {        //进入左子树        while(pointer!=NULL)        {            element.pointer=pointer;            element.tag=Left;            aStack.push(element);            pointer=pointer->leftchild();        }        //托出栈顶元素        element=aStack.top();        aStack.pop();        pointer=element.pointer;        //从右子树回来        while(element.tag==Right)        {            Visit(pointer->value());        //访问当前结点            if(aStack.empty())                return;            else            {                element=aStack.top();                aStack.pop();                pointer=element.pointer;            }        }        //从左子树回来        element.tag=Right;        aStack.push(element);        pointer=pointer->rightchild();    }}template<class T>vector<T> BinaryTree<T>::traversePostOrderWithoutRecusion() {    elements.clear();    PostOrderWithoutRecusion(root);    return elements;}template<class T>void BinaryTree<T>::PostOrderWithoutRecusion2(BinaryTreeNode<T>* root){//非递归后序遍历二叉树或其子树, 另一个版本//  using std::stack;    stack<BinaryTreeNode<T>* > aStack;    BinaryTreeNode<T> *p, *q;    if(root==NULL)        return;    p=root;    do{        while(p!=NULL)                          //沿左路分支下降                   {            aStack.push(p);            p=p->leftchild();        }        q=NULL;        while(!aStack.empty())        {            p=aStack.top();            aStack.pop();            if(p->rightchild()==q)              //右子树为空或刚刚被访问过            {                Visit(p->value());      //访问当前结点                q=p;            }            else            {                aStack.push(p);                p=p->rightchild();                break;            }        }    }while(!aStack.empty());}template<class T>vector<T> BinaryTree<T>::traversePostOrderWithoutRecusion2() {    elements.clear();    PostOrderWithoutRecusion2(root);    return elements;}template<class T>void BinaryTree<T>::LevelOrder(BinaryTreeNode<T>* root) //按层次遍历二叉树或其子树,这里使用队列来模拟{//  using std::queue;    queue<BinaryTreeNode<T>*> aQueue;    BinaryTreeNode<T>* pointer=root;    if(pointer)        aQueue.push(pointer);    while(!aQueue.empty())    {        pointer=aQueue.front();        Visit(pointer->value());        //访问当前结点        aQueue.pop();        if(pointer->leftchild())            aQueue.push(pointer->leftchild());        if(pointer->rightchild())            aQueue.push(pointer->rightchild());    }}template<class T>vector<T> BinaryTree<T>::traverseLevelOrder() {    elements.clear();    LevelOrder(root);    return elements;}

//BinarySearchTree.h

#pragma once#include "BinaryTreeNode.h"#include "BinaryTree.h"template <class T>class BinarySearchTree:public BinaryTree<T> {public:    BinarySearchTree(){};    virtual ~BinarySearchTree(){};    void InsertNode(BinaryTreeNode<T>* newpointer);    void DeleteNode(BinaryTreeNode<T>* pointer);};template <class T>void BinarySearchTree<T>::InsertNode(BinaryTreeNode<T>* newpointer){    BinaryTreeNode<T>* pointer=NULL; //初始化      if(root==NULL) {        //用指针newpointer初始化二叉搜索树树根,赋值实现        Initialize(newpointer);        return;    }    else pointer=root;    while(1)    {        if(newpointer->value()==pointer->value())            return ;                                    //相等则不用插入        else if(newpointer->value()<pointer->value())   //作为左子树        {            if(pointer->leftchild()==NULL)  {                pointer->left=newpointer;                return;            }            else    pointer=pointer->leftchild();        }        else{                                           //作为右子树            if(pointer->rightchild()==NULL){                pointer->right=newpointer;                return;            }            else    pointer=pointer->rightchild();        }    }}template <class T>void BinarySearchTree<T>::DeleteNode(BinaryTreeNode<T>* pointer){       if( pointer == NULL )   //如果带删除节点为空,返回        return;     BinaryTreeNode<T> * parent = GetParent(root ,pointer ); //保存要删除节点的父节点       if( pointer->leftchild() == NULL )  //如果待删除节点的左子树为空,就将它的右子树代替它即可    {               if( parent == NULL )                      //将右子树连到待删除节点的父的合适位置            root = pointer->rightchild();        else if( parent->leftchild() == pointer )            parent->left = pointer->rightchild();        else            parent->right = pointer->rightchild();        delete pointer;        pointer=NULL;        return;    }    //当待删除节点左子树不为空,就在左子树中寻找最大节点替换待删除节点    BinaryTreeNode<T> * temppointer;  //保存要替换上来的节点      BinaryTreeNode<T> * tempparent = NULL;  //保存要替换上来的节点的父节点        temppointer = pointer->leftchild();         while(temppointer->rightchild() != NULL )    {        tempparent = temppointer;        temppointer = temppointer->rightchild();    }    //删除替换结点    if(tempparent==NULL)        pointer->left=temppointer->leftchild();    else        tempparent->right=temppointer->leftchild();    //用替换结点去替代真正的删除结点    if(parent==NULL)        root=temppointer;    else if( parent->leftchild() == pointer )        parent->left=temppointer;    else parent->right=temppointer;    temppointer->left=pointer->leftchild();    temppointer->right=pointer->rightchild();    delete pointer;    pointer=NULL;    return;}
0 0
原创粉丝点击