数据结构-二叉搜索树

1.二叉搜索树的基本操作——自己准备校招用的——不喜勿喷哦

本人将,重复的节点,只保存了数量。但是输出的时候却没有输出所有的节点,想要输出所有的节点,自己加个for循环即可哦

#include <iostream>
#include <queue>
using namespace std;
struct jian{
    int key;
    int num;
    jian *lc;
    jian *rc;
};
queue<jian*> q;
queue<jian*> p;
/**
* 创建树
*/
jian *create(jian *root,int x){
    if(root==NULL){
        root=new jian;
        root->key=x;
        root->num=1;
        root->lc=NULL;
        root->rc=NULL;
    }else{
        if(root->key==x){
            root->num++;
        }else if(root->key<x){
            root->rc=create(root->rc,x);
        }else{
            root->lc=create(root->lc,x);
        }
    }
    return root;
}
/**
* 前序遍历
*/
void xianxu(jian *root)
{
    if(root!=NULL){
        cout<<root->key<<" ";
        xianxu(root->lc);
        xianxu(root->rc);
    }
}
/**
*   中序遍历
*/
void zhongxu(jian *root)
{
    if(root!=NULL){

        zhongxu(root->lc);
        cout<<root->key<<" ";
        zhongxu(root->rc);
    }
}
/**
*   后序遍历
*/
void houxu(jian *root)
{
    if(root!=NULL){

        houxu(root->lc);
        houxu(root->rc);
        cout<<root->key<<" ";
    }
}
/**
*   层次遍历,两个队列,一个是按照层次取值,找出左右子树,放入队列,删掉队列首,
*   一个是,存放取出的节点
*/
void cengcibianli(jian *root){
    if(q.empty()){
        q.push(root);
    }

    while(!q.empty()){
        jian *tree=q.front();
        if(tree->lc!=NULL){
            q.push(tree->lc);
        }
        if(tree->rc!=NULL){
            q.push(tree->rc);
        }
        p.push(tree);
        q.pop();
    }

}
/**
*   在二叉搜索树中,最大的值一定是在左子树中的
*   当节点的左子树为空的话,那么这个点就是最小值的节点,自己画个图看看
*/
jian *findMin(jian *root){
    if(root->lc==NULL)
    {
        cout<<root->key<<endl;
        return root;
    }
    if(root->lc!=NULL){
        findMin(root->lc);
    }
}
/**
*在二叉搜索树中,最大的值一定是在右子树中的,
*当结节的右子树为空的话,那么这个节点就是最大值的节点
*/
jian *findMax(jian *root){
    if(root->rc==NULL)
    {
        cout<<"所在的树的最大值是:"<<root->key<<endl;
        return root;
    }
    if(root->rc!=NULL){
        findMax(root->rc);
    }
}
/**
* 删除最小的那个值
*/
jian *removeMin(jian *root){
    if(root==NULL){
        return NULL;
    }
    if(root->lc==NULL){
            /**
            * 如果左子树是空的那么,返回右子树的地址,纵然是null也无所谓
            */
        jian* rightRc=root->rc;
        //delete root;
        return rightRc;//返回的地址,被上一个节点连接
    }
    root->lc=removeMin(root->lc);
    return root;
}
jian *removeMax(jian *root){
    if(root==NULL){
        return NULL;
    }
    //删除最大的,肯定是在右子树旁边找,删除某一个最大值,只要再把子树移到上边就行
    //树的结构不会发生变化
    //当key所在的节点没有右孩子的时候,那么就可以,将左孩子一上去,
    //递归函数的返回值是非常重要的
    //删除最小值同理
    if(root->rc==NULL){
        jian *leftLc=root->lc;
        //delete root;
        return leftLc;
    }
    root->rc=removeMax(root->rc);
    return root;
}
jian* removeKey(jian *root,int key)
{
    if(root==NULL){
        cout<<"不存在该节点"<<endl;
        return NULL;
    }
    /**
    * 先找出对应key的节点的地址
    */
    if(root->key>key){
        root->lc=removeKey(root->lc,key);
        return root;
    }else if(root->key<key){
        root->rc=removeKey(root->rc,key);
        return root;
    }else{ 
        //key==root->key
        /**
        * 找到节点对应的地址
        *  1.如果左子树为空的树,说明是个最小值,删除节点,将子树移上去结构不变
        */
        if(root->lc==NULL){
            jian *rightRc=root->rc;
            delete root;
            return rightRc;
        }
         /**
        * 找到节点对应的地址
        *  1.如果右子树为空的树,说明是个最大值,删除节点,将子树移上去结构不变
        */
        if(root->rc==NULL){
            jian *leftLc=root->lc;
            delete root;
            return leftLc;
        }
        //左右子树都不为空的时候,
        /**
        *   左右子树都不为空的时候
        *   1.以当前节点的右子树的节点值为根,寻找右子树的最小值,作为替换,key所对应的节点
        *   2.返回的地址的右子树连接key对应节点的右子树删除最小值的新树
        *   3.左子树不变
        *   4其实寻找替换节点还可以用左子树的对应的最大值
        */
        jian *tree=findMin(root->rc);//寻找右子树中最小的值,当节点
        tree->rc=removeMin(root->rc);//
        tree->lc=root->lc;
        return tree;
    }
}
int main()
{
    int i;
    //int a[5]={5,2,4,8,6};
    int a[7]={10,7,4,9,12,13,11};
    jian *root;
    root=NULL;
    for(i=0;i<7;i++){
        root=create(root,a[i]);
    }
    //xianxu
    cout<<"前序遍历"<<endl;
    xianxu(root);
     cout<<endl;
   cout<<"中序遍历,其实就是从小到大排序!"<<endl;
    zhongxu(root);
     cout<<endl;
    cout<<"后序遍历"<<endl;
    houxu(root);
    cout<<endl;

    cout<<"层次遍历"<<endl;
    cengcibianli(root);
    while(!p.empty()){
        jian *tree=p.front();
        cout<<p.front()->key<<" ";
        p.pop();
    }
    cout<<endl;
    cout<<"删除最小值"<<endl;
    /*
    * 最小值是左子树中,最左边的值
    */
    findMin(root);
    cout<<"删除最大值"<<endl;
    /**
    *最大值是右子树中最右边的值
    */
    findMax(root);
    cout<<"删除二叉搜索树中的某个节点"<<endl;

    cout<<"先查找某一个节点"<<endl;
    //jian* tree;
    //tree=searchValue(2);
    cout<<"zainane"<<endl;
    int searchKey=12;
    root=removeKey(root,searchKey);

    cengcibianli(root);
    while(!p.empty()){
        jian *tree=p.front();
        cout<<p.front()->key<<" ";
        p.pop();
    }

}















/*queue<jian*> q;
queue<jian*> p;
jian* create(jian *root,int x){
    if(root==NULL){
            //这里创建的二叉搜索树,重复元素,用个数代替
        root=new jian;
        root->key=x;
        root->lc=NULL;
        root->rc=NULL;
        root=new jian;
        root->key=x;
        root->num=1;
        root->lc=NULL;
        root->rc=NULL;
    }

    else
    {
         if(x>root->key)
        {
            root->rc=create(root->rc,x);
        }
        else
        {
            root->lc=create(root->lc,x);
        }
        if(x>root->key){
            root->rc=create(root->rc,x);
        }else if(x<root->key){
            root->lc=create(root->lc,x);
        }else{
            root->num++;
        }

    }
    return root;
}
void bianli(jian *root){
    if(q.empty()){
        q.push(root);
    }
    jian *tree=q.front();
    if(tree->lc!=NULL){
        q.push(tree->lc);
    }
    if(tree->rc!=NULL){
        q.push(tree->rc);
    }
    p.push(tree);
    q.pop();
}

int main()
{
    jian* root;
    int x,i;
    int a[5]={5,4,6,2,8};
    for(i=0;i<5;i++)
    {
        root=create(root,a[i]);
    }


    //bfs层次遍历一下
   // bianli(root);
    while(!p.empty()){
        jian *tree=p.front();
        cout<<p.front()->key<<" "<<endl;
        p.pop();
    }
}*/

先展示下效果 https://pan.quark.cn/s/e81b877737c1 Node.js 是一种基于 Chrome V8 引擎的 JavaScript 执行环境,它使开发者能够在服务器端执行 JavaScript 编程,显著促进了全栈开发的应用普及。 在 Node.js 的开发流程中,`node_modules` 文件夹用于存储所有依赖的模块,随着项目的进展,该文件夹可能会变得异常庞大,其中包含了众多可能已不再需要的文件和文件夹,这不仅会消耗大量的硬盘空间,还可能减慢项目的加载时间。 `ModClean 2.0` 正是为了应对这一挑战而设计的工具。 `ModClean` 是一款用于清理 `node_modules` 的软件,其核心功能是移除那些不再被使用的文件和文件夹,从而确保项目的整洁性和运行效率。 `ModClean 2.0` 是此工具的改进版本,在原有功能上增加了更多特性,从而提高了清理工作的效率和精确度。 在 `ModClean 2.0` 中,用户可以设置清理规则,例如排除特定的模块或文件类型,以防止误删重要文件。 该工具通常会保留项目所依赖的核心模块,但会移除测试、文档、示例代码等非运行时必需的部分。 通过这种方式,`ModClean` 能够协助开发者优化项目结构,减少不必要的依赖,加快项目的构建速度。 使用 `ModClean` 的步骤大致如下:1. 需要先安装 `ModClean`,在项目的根目录中执行以下命令: ``` npm install modclean -g ```2. 创建配置文件 `.modcleanrc.json` 或 `.modcleanrc.js`,设定希望清理的规则。 比如,可能需要忽略 `LICENSE` 文件或整个 `docs`...
2026最新微信在线AI客服系统源码 微信客服AI系统是一款基于PHP开发的智能客服解决方案,完美集成企业微信客服,为企业提供7×24小时智能客服服务。系统支持文本对话、图片分析、视频分析等多种交互方式,并具备完善的对话管理、人工转接、咨询提醒等高级功能。 核心功能 ### 1.  智能AI客服 #### 自动回复 - **上下文理解**:系统自动保存用户对话历史,AI能够理解上下文,提供连贯的对话体验 - **个性化配置**:可自定义系统提示词、最大输出长度等AI参数 #### 产品知识库集成 - **公司信息**:支持配置公司简介、官网、竞争对手等信息 - **产品列表**:可添加多个产品,包括产品名称、配置、价格、适用人群、特点等 - **常见问题FAQ**:预设常见问题及答案,AI优先使用知识库内容回答 - **促销活动**:支持配置当前优惠活动,AI会自动向用户推荐 ### 2. 多媒体支持 #### 图片分析 - 支持用户发送图片,AI自动分析图片内容 - 可结合文字描述,提供更精准的分析结果 - 支持常见图片格式:JPG、PNG、GIF、WebP等 #### 视频分析 - 支持用户发送视频,AI自动分析视频内容 - 视频文件自动保存到服务器,提供公网访问 - 支持常见视频格式:MP4、等 ### 3.  人工客服转接 #### 关键词触发 - **自定义关键词**:可配置多个转人工触发关键词(如:人工、客服、转人工等) - **自动转接**:用户消息包含关键词时,自动转接给指定人工客服 - **友好提示**:转接前向用户发送提示消息,提升用户体验 #### 一键介入功能 - **后台管理**:管理员可在对话管理页面查看所有对话记录 - **快速转接**:点击"一键介入"按钮,立即将用户转接给人工客服
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值