数据结构 二叉搜索树的相关操作

这个地方我感觉理解简单,但是把自己想的转化为代码还是有点困难的,这篇文章主要包括了二叉搜索树的构造,前序遍历,中序遍历,后序遍历,层次遍历,节点的数目,高度等相关操作,下面是代码:

main.cpp

//
//  main.cpp
//  BinaryTreeDemo
//
//  Created by xin wang on 4/16/15.
//  Copyright (c) 2015 xin wang. All rights reserved.
//

#include <iostream>
#include "queue.h"

class BadInput{
public:
    BadInput(){
        std::cout<<"empty tree"<<std::endl;
    }
};

//链表二叉树的节点类
template <class T>
class BinaryTreeNode{
public:
    BinaryTreeNode(){LeftChild = RightChild=0;}
    BinaryTreeNode(const T& e){
        data=e;
        LeftChild=RightChild =0;
    }
    BinaryTreeNode(const T& e,BinaryTreeNode *l,BinaryTreeNode *r){
        data = e;
        LeftChild =l;
        RightChild =r;
    }
    T data;
    BinaryTreeNode<T> *LeftChild,*RightChild;
};


template <class T>
class BinaryTree{
public:
    BinaryTree(){root =0;}
    ~BinaryTree(){};
    bool IsEmpty()const{
        return ((root)  ? false : true);
    }
    bool Root(T& x)const;
    void MakeTree(const T& element,BinaryTree<T>& left,BinaryTree<T>& right);//产生一棵树
    void BreakTree(const T& element,BinaryTree<T>& left,BinaryTree<T> &right);//拆掉一棵树
    void PreOrder(void(*Visit)(BinaryTreeNode<T> *u)){PreOrder(Visit,root);}//前序遍历
    void InOrder(void(*Visit)(BinaryTreeNode<T> *u)){InOrder(Visit,root);}//中序遍历
    void PostOrder(void(*Visit)(BinaryTreeNode<T> *u)){PostOrder(Visit,root);}//后序遍历
    void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u)){LevelOrder(Visit,root);}//层次遍历
    void GernerateTree(T& u);//构造一棵树

    //二叉树的扩充
    void PreOutput();//输出前序遍历
    void InOutput();//输出中序遍历
    void PostOutput();//输出后序遍历
    void LevelOutput();//输出层次遍历
    void Delete();//删除节点
    int Height(BinaryTreeNode<T> *t)const;//计算树的高度
    int Size();//计算节点数
    BinaryTreeNode<T> *root;//根节点

private:
    void PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
    void InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
    void PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
    void LevelOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t);
};

//返回是否是根节点
template <class T>
bool BinaryTree<T>::Root(T& x)const{
    if (root) {
        x=root->data;
        return true;
    }else{
        return false;
    }
}

template <class T>
void BinaryTree<T>::MakeTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right){
    //创建新树
    root = new BinaryTreeNode<T>(element,left.root,right.root);
    //阻止访问left和right
    left.root = right.root =0;
}

template <class T>
void BinaryTree<T>::BreakTree(const T& element, BinaryTree<T>& left, BinaryTree<T>& right){
    if (!root) {
        throw BadInput();
    }
    element = root->data;
    left.root = root->LeftChild;
    right.root = root->RightChild;
    delete root;
    root=0;
    
}
//前序遍历
template <class T>
void BinaryTree<T>::PreOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
    if (t) {
        Visit(t);
        PreOrder(Visit,t->LeftChild);
        PreOrder(Visit,t->RightChild);
        
    }
}

//中序遍历
template <class T>
void BinaryTree<T>::InOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
    if(t){
        InOrder(Visit,t->LeftChild);
        Visit(t);
        InOrder(Visit, t->RightChild);
    }
    
}

//后序遍历
template <class T>
void BinaryTree<T>::PostOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *t){
    if (t) {
        PostOrder(Visit,t->LeftChild);
        PostOrder(Visit,t->RightChild);
        Visit(t);
    }
}

//层次遍历
template <class T>
void BinaryTree<T>::LevelOrder(void(*Visit)(BinaryTreeNode<T> *u),BinaryTreeNode<T> *u){
    
    LinkedQueue<BinaryTreeNode<T> *> Q;
    BinaryTreeNode<T> *t;
    t=root;
    while (t) {
        Visit(t);
        if (t->LeftChild) {
            Q.Add(t->LeftChild);
        }
        if (t->RightChild) {
            Q.Add(t->RightChild);
            
        }
        try{
            Q.Delete(t);

        }catch(OutOfBounds){
            return;
        }
    }
    
    
    
    
}
//计算树的高度
template <class T>
int BinaryTree<T>::Height(BinaryTreeNode<T> *t)const{
    if (!t) {
        return 0;
    }
    int hl=Height(t->LeftChild);
    int hr = Height(t->RightChild);
    if (hl>hr) {
        
        return ++hl;
    }else{
        return ++hr;
    }
}

int _count;
template <class T>
static void Add1(BinaryTreeNode<T> *t){
    _count++;
}

//计算节点数
template <class T>
int BinaryTree<T>::Size(){
    _count=0;
    PreOrder(Add1,root);
    return _count;
}


//输出
template <class T>
static void OutPut(BinaryTreeNode<T> *t){
    std::cout<<t->data<<" ";
}

template <class T>
void BinaryTree<T>::PreOutput(){
    PreOrder(OutPut,root);
}

template <class T>
void BinaryTree<T>::InOutput(){
    InOrder(OutPut,root);
}

template <class T>
void BinaryTree<T>::PostOutput(){
    PostOrder(OutPut,root);
}

template <class T>
void BinaryTree<T>::LevelOutput(){
    LevelOrder(OutPut,root);
}

//构造一棵树
template <class T>
void BinaryTree<T>::GernerateTree(T& u){
    if (!root) {//如果没有根的话,就新建一个根节点,并赋给他根节点的值
        root = new BinaryTreeNode<T>;
        root->data =u;
        root->LeftChild=0;
        root->RightChild=0;
        return;
    }
    //如果有根节点的话
    BinaryTreeNode<T> *newNode = new BinaryTreeNode<T>;
    newNode->data = u;
    LinkedQueue<BinaryTreeNode<T> *>myQueue;
    BinaryTreeNode<T> *t;
    t=root;
    
    while(t){
        std::cout<<"t.data"<<t->data<<std::endl;
        if (t->LeftChild) {//如果有左孩子的话
            myQueue.Add(t->LeftChild);//就加到队列里面
            std::cout<<"Left is"<<t->LeftChild->data<<std::endl;
        }
        if (t->RightChild) {//如果有右孩子的话,就加到队列里面
            myQueue.Add(t->RightChild);
            std::cout<<"Right is"<<t->RightChild->data<<std::endl;
        }
        
        if (!t->LeftChild) {//如果没有左孩子的话,就让新的节点为左孩子
            std::cout<<"Put "<<newNode->data<<" in Left"<<std::endl;
            t->LeftChild=newNode;
            return;
        }else{
            std::cout<<"t.Leftdata="<<t->LeftChild->data<<std::endl;

        }
        if(!t->RightChild){//如果没有右孩子的话,就让新的节点为右孩子
            std::cout<<"Put "<<newNode->data<<" in Right"<<std::endl;
            t->RightChild=newNode;
            return;
        }else{
            std::cout<<"t.Rightdata="<<t->RightChild->data<<std::endl;

        }
        
        if (!myQueue.IsEmpty()) {//对队列里面的数再进行如上判断
            myQueue.Delete(t);
        }
    }
    
    
}


int main()
{
    BinaryTree<int> y;
    int myInput;
    while (true) {
        std::cin>>myInput;
        if (myInput == 0) {
            break;
        }else{
            y.GernerateTree(myInput);
        }
    }
    std::cout<<"前序遍历:";
    y.PreOutput();
    std::cout<<"中序遍历:";
    y.InOutput();
    std::cout<<"后序遍历:";
    y.PostOutput();
    std::cout<<"逐层遍历";
    y.LevelOutput();
    std::cout<<"高度:";
    std::cout<<y.Height(y.root)<<std::endl;
    std::cout<<"节点数:";
    std::cout<<y.Size()<<std::endl;
    return 0;
}

queue.h

//
//  queen.h
//  BinaryTreeDemo
//
//  Created by xin wang on 4/17/15.
//  Copyright (c) 2015 xin wang. All rights reserved.
//

template <class T>
class Node{
public:
    T data;
    Node<T> *link;
};

//FIIFO对象
template <class T>
class LinkedQueue{
public:
    LinkedQueue(){front=rear=0;}
    ~LinkedQueue();
    bool IsEmpty()const{return ((front)?false:true);}
    bool IsFull()const;
    T First()const;     //返回队首元素
    T Last()const;      //返回队尾元素
    LinkedQueue<T>& Add(const T& x);
    LinkedQueue<T>& Delete(T& x);
    void Output();
    Node<T> *front;               //指向第一个节点
    Node<T> *rear;                //最后一个节点
    
    
};

template <class T>
LinkedQueue<T>::~LinkedQueue(){
    Node<T> *next;
    while (front){
        next = front->link;
        delete front;
        front = next;
    }
}

class OutOfBounds{
public:
    OutOfBounds(){
        //cout<<"Out Of Bounds!"<<endl;
    }
};


//内存不足的异常类
class NoMem{
public:
    NoMem(){
        std::cout<<"No Memory!"<<std::endl;
    }
};


//该队列的输出方法
template<class T>
void LinkedQueue<T>::Output(){
    Node<T> *temp = front;
    while(temp){
        std::cout<<temp->data<<" ";
        temp=temp->link;
    }
    std::cout<<""<<std::endl;
}

//判断当前队列是否已满
template <class T>
bool LinkedQueue<T>::IsFull()const{
    Node<T>*p;
    try{
        p = new Node<T>;
        delete p;
        return false;
    }
    catch (NoMem)
    {
        return true;
    }
}


//返回队列的第一个元素
template <class T>
T LinkedQueue<T>::First()const{
    if(IsEmpty())
        throw OutOfBounds();
    return front->data;
}

//返回队列的最后一个元素
template <class T>
T LinkedQueue<T>::Last()const{
    if(IsEmpty())
        throw OutOfBounds();
    return rear->data;
}

//将x添加到队列的尾部
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Add(const T&x){
    Node<T>*p = new Node<T>;
    p->data=x;
    p->link=0;
    //在队列尾部添加新节点
    if (front){
        rear->link = p;
    }
    else{
        front=p;
    }
    rear=p;
    return *this;
}


//删除第一个元素并将其放到X中去
template<class T>
LinkedQueue<T>& LinkedQueue<T>::Delete(T&x){
    if (IsEmpty()){
        throw OutOfBounds();
    }
    x = front->data;
    Node<T>*p = front;
    front = front->link;
    delete p;
    return *this;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值