C++数据结构 17 二叉查找树

Bst(Binary Search Tree)

有以下性质:

  • 每一个元素有一个键值,而且不予许重复

  • 左子树的键值都小于根节点的键值

  • 右子树的键值都大于根节点的键值

  • 左右子树都是二叉查找树

代码:

#ifndef __BST_H__
#define __BST_H__
#include<iostream>
using namespace std;
template <class T> class Bst; //声明

enum Boolean {False,True};
template<class T>
class Element   //数据
{
  public:
      T Key;     //定义键值
};



template<class T>
class BstNode   //定义结点
{
    friend class Bst<T>;
public:
    Element<T> data; //结点数据
    BstNode *LeftChild; //左孩子
    BstNode *RightChild;//右孩子
    void display(int i); //显示
};

template<class T>
class Bst          //定义二叉查找树
{
public:
    Bst(BstNode<T>*init=0)  //定义构造函数
    {
      root=init;
    }
    Boolean Insert(Element<T>&x);  //插入元素
    BstNode<T>* Search(const Element<T>&x);  //递归查找
    BstNode<T>* Search(BstNode<T>*p,const Element<T>&x);
    BstNode<T>* ItearSearch(const Element<T>&x);   //采用迭代方式查找
    void display()
    {
        cout<<endl;
        if(root)
            root->display(1); //根从1开始显示

    }
    void Preorder(BstNode<T> *CurrentNode); //前序遍历
    void Inorder(BstNode<T> *CurrentNode);  //中序遍历
    void Postorder(BstNode<T> *CurrentNode);//后序遍历
    void Vivit(BstNode<T> *CurrentNode); //当前节点
//private:
    BstNode<T>*root;  //根结点
};

template<class T>
void BstNode<T>::display(int i)   //显示数据
{
   cout<<"Position: "<<i<<" Data:"<<data.Key<<endl;  //显示位置和数据
   if(LeftChild) LeftChild->display(2*i);       //显示左孩子
   if(RightChild) RightChild->display(2*i+1);   //显示右孩子
}

template<class T>
Boolean Bst<T>::Insert(Element<T>&x)  //插入数据
{
    //插入数据之前需要查找数据
    BstNode<T> *p=root; //初始指向根节点
    BstNode<T> *q=0;    //用来保存上一个父节点
    while(p)
    {
       q=p;       //保存上一个父节点
       if(x.Key==p->data.Key)  return False;  //如果节点存在 则返回错误
       if(x.Key>p->data.Key) p=p->RightChild; //如果节点父节点大,则放到右节点
       else p=p->LeftChild;                   //否则,放到左节点
    }
    //找到的位置就是q
    p=new BstNode<T>;
    p->LeftChild=p->RightChild=0;  //刚开始令左孩子和右孩子都等于0
    p->data=x;
    if(!root) root=p;   //如果根不存在 p就是根
    else if(x.Key>q->data.Key) q->RightChild=p;  //键值比父节点大,则放到右孩子
    else q->LeftChild=p;                      //否则,放到左孩子
    return True;             //返回正确
}

template<class T>
BstNode<T>* Bst<T>::Search(const Element<T>&x) //查找
{
   return Search(root,x); //从根开始查找
}

template<class T>
 BstNode<T>* Bst<T>::Search(BstNode<T>*p,const Element<T>&x)
{
  if(!p) return 0; //如果b不存在 返回0
  if(x.Key==p->data.Key) return p;    //找到了 返回p
  if(x.Key>p->data.Key) Search(p->RightChild,x);  //比父节点大 从右开始找
  else Search(p->LeftChild,x);         //否则 从左开始找
}

template<class T>
BstNode<T>* Bst<T>::ItearSearch(const Element<T>&x)//采用迭代方式查找
{
    BstNode<T>*p;
  for(p=root;p;)  //p等于root p有效就一直查找
  {
    if(x.Key==p->data.Key) return p;
    if(x.Key>p->data.Key) p=p->RightChild;  //如果大于则p指向下一个右孩子
    else p=p->LeftChild;       //否则 指向左孩子
  }
  //循环结束都没找到
  return 0; //
}
static int cnt=0;  //节点数
/*遍历*/
template<class T>
void Bst<T>::Vivit(BstNode<T> *CurrentNode)
{
   cout<<CurrentNode->data.Key<<' ';   //显示当前数据键值
}

template<class T>
void Bst<T>::Preorder(BstNode<T> *CurrentNode)//前序遍历
{
   if(CurrentNode)
   {
       Vivit(CurrentNode);
       Preorder(CurrentNode->LeftChild); //左子树
       Preorder(CurrentNode->RightChild); //右子树
   }
}

template<class T>
void Bst<T>::Inorder(BstNode<T> *CurrentNode)//中序遍历
{
     if(CurrentNode)
   {

       Preorder(CurrentNode->LeftChild); //左子树
       Vivit(CurrentNode);
       Preorder(CurrentNode->RightChild); //右子树
   }
}

template<class T>
void Bst<T>::Postorder(BstNode<T> *CurrentNode)//后序遍历
{
    if(CurrentNode)
   {

       Preorder(CurrentNode->LeftChild); //左子树
       Preorder(CurrentNode->RightChild); //右子树
       Vivit(CurrentNode);
   }
}

#endif // __BST_H__

main

#include <iostream>
#include "BST.h"
using namespace std;

int main()
{
    Bst<int> p;
    Element<int>a,b,c,d,e,f,g,h,i,l,k;
    a.Key=5;
    b.Key=3;
    c.Key=11;
    d.Key=3;
    e.Key=15;
    f.Key=2;
    g.Key=8;
    h.Key=22;
    i.Key=20;
    l.Key=9;
     cout<<p.Insert(a)<<endl;
     cout<<p.Insert(b)<<endl;
     cout<<p.Insert(c)<<endl;
     cout<<p.Insert(d)<<endl;
     cout<<p.Insert(e)<<endl;
     cout<<p.Insert(f)<<endl;
     cout<<p.Insert(g)<<endl;
     cout<<p.Insert(h)<<endl;
     cout<<p.Insert(i)<<endl;
     cout<<p.Insert(l)<<endl;
      p.display();
      BstNode<int> *m=p.ItearSearch(i);
      cout<<m->data.Key<<endl;
    //cout << "Hello world!" << endl;
    cout<<"前序遍历"<<endl;
    p.Preorder(p.root);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值