栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

二叉查找树

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二叉查找树

1 二叉查找树类的定义
//建立集合
template 
struct SET
{
    KEY key;
    OTHER other;
};
//建立动态查找表的类
template
class dynamicSearchTable
{
public:
    virtual SET*find(const KEY&x)const=0;
    virtual void insert(const SET&x)=0;
    virtual void remove(const KEY&x)=0;
    virtual ~dynamicSearchTable(){};
};
template
class BinarySearchTree:public dynamicSearchTable
{
private:
    struct binaryNode
    {
        SET data;
        binaryNode*left;
        binaryNode*right;

        binaryNode(const SET&data1,binaryNode*left1=NULL,binaryNode*right1=NULL):data(data1),left(left1),right(right1){}
        ~binaryNode(){}
    };
    binaryNode*root;
public:
    BinarySearchTree(){root=NULL;};
    ~BinarySearchTree(){makeEmpty(root);};

    SET*find(const KEY&x)const{find(x,root);};//const在结尾表示这个函数不改变这个类
    void insert(const SET&x){insert(x,root);};
    void remove(const KEY&x){remove(x,root);};

private:
    SET*find(const KEY&x,binaryNode*t)const;
    void insert(const SET&x,binaryNode*&t);
    void remove(const KEY&x,binaryNode*&t);
    void makeEmpty(const binaryNode*&t);

};

注意区分引用&与取地址*

2 二叉查找树功能实现 2.1 find函数的实现 2.1.1 递归方法
template
SET* BinarySearchTree:://注意所属于类后如果有模板,也要带上
    find(const KEY&x,binaryNode*t)const
{
//无法返回结构体,因此只能返回结构体指针,这样才能通过序号索引到一些对应内容
  if(t==NULL) return NULL;
  if(t->data==x)  return &(t->data);//返回结构体元素的地址,区分t指向节点地址,通过节点地址找到节点,访问节点得到结构体地址
    //上一行写return t是不对的,因为t是binaryNode地址
  //要返回的是SET*,但t指向的是一个SET结构体
  //因此要强制类型转换,如return (SET*)t
  else
  {
      if(t->dataleft);
      else return find(x,t->right);
  }
}
2.1.2 非递归方法
template
SET* BinarySearchTree::
    find(const KEY&x)const
{
//无法返回结构体,因此只能返回结构体指针,这样才能通过序号索引到一些对应内容
  if(root==NULL) return NULL;
  binaryNode*p=root;
  while(p)//二叉树到叶子后面停止
  {
     if(p->data==x) return &(t->data);//取地址运算符&
     if(p->dataleft;
     else p=p->right;

  }
  return NULL;
}

注意非递归结尾没有找到时中止标志,到叶子会自动退出,要自己输入NULL,递归在判断结点是否为空时,就已经可以输出NULL表示结束没有找到了

2.2 insert函数

大体理论是任何被插入的结点最后一定可以成为叶子结点
从上到下比较

template
void BinarySearchTree::insert(const SET&x,binaryNode*&t)
{
    if(t==NULL)
    {t=new binaryNode(x);
    return;}//为结构体新建一个结点
    if(t->data==x.key) return;//已经存在则结束插入,无需调用find
    if(x.key>t->data) insert(t->right,x);
    else insert(t->left,x);
    //注意此处x为结构体,要访问key比大小
}

由insert构建可知,左子树的最大值小于右子树的根结点值
右子树的最小值大于左子树的根结点值

2.3 remove函数
void BinarySearchTree::remove(const KEY&x,binaryNode*&t)
{
   //先进行查找
    if(t==NULL) return;
    if(t->data.keyleft);
    else
    {
        if(t->data.key>x) remove(x,t->right);
        else
        {
            if(t->left&&t->right)
            {
                binaryNode*tmp=t->left;
                while(tmp->right) tmp=tmp->right;//找到左子树中的最大值
                t->data=tmp->data;//用左子树最大值替换被删结点
                //但这样就很难删掉t,if(tmp->left)tmp=tmp->left;//或者remove(x,tmp->left)
                //将替换结点左子树放到替换节点位置
                remove(t->data.key,tmp->left);//删除左子树最大值,用下面else删掉,妙!
            }
            else
            {
                binaryNode*OldNode=t;//*****
                if(t->left) t=t->left;
                if(t->right) t=t->right;
                delete OldNode;
            }

        }
    }
}

比较巧妙或者易错的有删除操作

*时间复杂度

如果树接近完全二叉树,时间复杂度O(logN)
最差情况是退化为一个单链表,时间复杂度O(n)
由此引入下一章节内容,AVL平衡二叉树,改变二叉树结构,避免退化成单链表情况

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917107.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号