首页 > 编程语言 >二叉查找树的实现C/C++

二叉查找树的实现C/C++

时间:2023-11-06 17:46:50浏览次数:40  
标签:node root C++ 二叉 binTree 查找 rchild NULL data

二叉查找树是一种关键字有序存放的二叉树。在不含重复关键字的二叉查找树中,关键字"较小"的节点一定在关键字“较大”的节点的左子树中,“较小”一般可以由内值类型的<运算符来实现,或由重载了<运算符的类类型的<运算符来实现。“较小”的概念可以根据我们的需要有不同的实现。本文实现一个关键字类型为elemType的二叉查找树,elemType可以是内置类型,也可以是自定义类型,如果是自定义类型,二叉查找树要求类型实现一些比较运算符,能够定义"较大"、“较小”、”相等“、”不等“这些概念。

本文实现操作:

1. 层序遍历  2. 插入  3.删除

4.查找     5. 根据若干给定元素建树

 

0. 二叉查找树的定义

//binary tree
struct binTree
{
    elemType data;  
    binTree* lchild;
    binTree* rchild;
    binTree(elemType data):data(data),lchild(NULL),rchild(NULL) {};
};

 

1. 层序遍历

这里使用队列来实现层序遍历。并接受一个void (*) (const binTree* root) 类型的函数指针作为参数,定义遍历节点时要对节点进行的操作。

//层序遍历,对每一个节点执行函数指针pfun指定的操作
void layerOrderTravel(const binTree * root,void (*pfun) (const binTree* root) )
{
    if( root == NULL ) return ;
    std::queue<const binTree*> q;
    q.push(root);
    while(!q.empty())
    {
        const binTree* node = q.front();
        if( node->lchild != NULL ) q.push(node->lchild);
        if( node->rchild != NULL ) q.push(node->rchild);
        pfun(node);
        q.pop();
    }
    return ;
}

2. 插入

//在根为root的二叉查找树树中插入元素为x的节点
void BSTInsert(binTree*& root,elemType x)
{
    //root==NULL即找到了插入位置
    if( root == NULL )
    {
        root = new binTree(x);
        //cout << "正在插入" << x << endl;
        return ;
    }
    //对于不允许重复元素的树,若x已存在,直接返回。
    if( root->data == x ) return ;
    //在左子树中插入
    if( x < root->data )
        BSTInsert(root->lchild,x);
    //在右子树中插入
    if( x > root->data )
        BSTInsert(root->rchild,x);
}

 

3. 删除

//在root中删除值为x的节点
void BSTDelete(binTree*& root,elemType x)
{
    //
    if( root == NULL ) return ;
    //找到了要删除的节点
    if( root->data == x )
    {
        if( root->lchild == NULL && root->rchild == NULL )
        {
            //节点没有左右孩子,直接将该节点指针置空,其父节点中指向这个节点的lchild或rchild会相应地指向NULL
            root = NULL;
            return ;
        }
        //如果有左孩子,令其直接前驱代替其值,并递归地在左子树中删除其直接前驱
        else if( root->lchild != NULL )
        {
            binTree* node = root->lchild;
            while( node->rchild )
                node = node->rchild;
            root->data = node->data;
            BSTDelete(root->lchild,node->data);
        }
        else if( root->rchild != NULL )
        {
            binTree* node = root->rchild;
            while( node->lchild )
                node = node->lchild;
            root->data = node->data;
            BSTDelete(root->rchild,node->data);
        }
    }
    else if( x < root->data ) BSTDelete(root->lchild,x);
    else if( x > root->data ) BSTDelete(root->rchild,x);
}

 

4. 查找

//在根为root的树中查找值为x的节点
binTree* BSTFind( binTree* root,elemType x)
{
    if( root == NULL )
    {
        std::cout << "空树" << std::endl;
        //throw
        return NULL;
    }
    //找到了
    if( root->data == x )
        return root;
    //在右子树中查找
    if( root->data < x )
        return BSTFind(root->rchild,x);
    //在左子树中查找
    if( root->data > x )
        return BSTFind(root->lchild,x);

    //throw
    return NULL;
}

 

5. 建树

//由给定的元素序列elems创建一棵二叉查找树,返回树根节点的指针
binTree* createBST(const std::vector<elemType>& elems)
{
    binTree* root = NULL;
    for( std::vector<elemType>::const_iterator it = elems.begin(); it != elems.end(); ++it )
    {
        BSTInsert(root,*it);
    }
    return root;
}

 

标签:node,root,C++,二叉,binTree,查找,rchild,NULL,data
From: https://www.cnblogs.com/pkuqcy/p/17813216.html

相关文章

  • C++中如何返回数组类型数据
    错误示范:int*test01(){ intdata[3]={1,2,3}; returndata;}intmain(){ int*result=test01(); for(inti=0;i<3;i++){ cout<<result[i]<<'\t'; }}正确示范:int*test01(){// intdata[3]={1,2,3}; int*da......
  • C++逃离陨石
    题目描述在公元\(114514\)年小朱在学校里上课,突然听见学校广播播放一条骇人听闻的消息:一群陨石将袭击我市,由于陨石积过大数量多,它们无法在撞击到地面前燃烧殆尽,将会对它撞到的一切东西造成毁灭性的打击。小朱同志开始担心自己的安全问题。他一定要在被流星砸到前,到达一个......
  • C++最自信的鱼
    题目描述人比人,气死人;鱼比鱼,难死鱼。小鱼最近参加了一个“比可爱”比赛,比的是每只鱼的可爱程度。参赛的鱼被从左到右排成一排,头都朝向左边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都......
  • C++U5-04-广度优先搜索1
    广搜逻辑  广搜代码核心思路 广搜伪代码 思维导图1、[【广搜】走迷宫] 求最少需要多少步,考虑使用广搜。从起点开始进行搜索,规则只能向上下左右走动,当搜索到终点时就结束。广搜的核心思路:初始化一个队列和数组将起点入队并标记当队列不为空且没到终点的时候 取......
  • L-4: 34--在排序数组中查找元素的第一个和最后一个位置
    给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值 target,返回 [-1,-1]。你必须设计并实现时间复杂度为 O(logn) 的算法解决此问题。 示例1:输入:nums=[5,7,7,8,8,10],tar......
  • C++使用冒泡排序算法对数组进行排序
     #include<iostream>//包含iostream库usingnamespacestd;//使用标准命名空间intmain(){//主函数intarr[]={5,3,2,8,6,7,1,4};//定义并初始化数组intn=sizeof(arr)/sizeof(arr[0]);//计算数组长度//使用冒泡排序算法对数组进......
  • 二叉树理论基础
    二叉树理论基础二叉树的种类满二叉树、完全二叉树、二叉搜索树、平衡二叉搜索树二叉树的存储方式顺序存储、链式存储二叉树的遍历方式二叉树主要有两种遍历方式:深度优先遍历:先往深走,遇到叶子节点再往回走。广度优先遍历:一层一层的去遍历。那么从深度优先遍历和广度优先......
  • 01_二叉树的递归遍历
    二叉树的递归遍历递归算法的三要素确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数,并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。确定终止条件:写完了递归算法,运行的时候,经常会遇到栈溢出的错误,就是没写终......
  • 力扣905 按奇偶排序数组 C++ 双指针+一次遍历
    905.按奇偶排序数组classSolution{public:vector<int>sortArrayByParity(vector<int>&nums){inti=0,j=nums.size()-1;while(i<nums.size()-1&&i<j){while(i<j&&(nums[i]%2==0))i++;......
  • C++_18_多态 - 重写版
     多态:面向对象三大概念:封装、继承、多态!可想而知多态是何等的重要多态的概念以及前提条件:编译期绑定(静态联编):函数入口地址和函数名在编译期间绑定,即编译期间确定函数名和入口地址唯一对应运行期绑定(动态联编):函数入口地址和函数名在编译期间不绑定......