[数据结构]:10-二叉排序树(无头结点)(C语言实现)

news2024/11/20 6:22:40

目录

前言

已完成内容

二叉排序树实现

01-开发环境

02-文件布局

03-代码

01-主函数

02-头文件

03-BinarySearchTreeCommon.cpp

04-BinarySearchTreeFunction.cpp

结语


前言

        此专栏包含408考研数据结构全部内容,除其中使用到C++引用外,全为C语言代码。使用C++引用主要是为了简化指针的使用,避免二重指针的出现。

已完成内容

[数据结构]:01-顺序表(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:02-单链表(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:03-栈(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:04-循环队列(数组)(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:05-循环队列(链表)(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:06-队列(链表带头结点)(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:07-二叉树(无头结点)(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:08-顺序查找(顺序表指针实现形式)(C语言实现)_Chandni.的博客-CSDN博客

[数据结构]:09-二分查找(顺序表指针实现形式)(C语言实现)_Chandni.的博客-CSDN博客

二叉排序树实现

01-开发环境

        语言:C/C++14

        编译器:MinGW64

        集成开发环境:CLion2022.1.3

02-文件布局

        请在CLion集成开发环境中创建C++可执行程序,否则无法运行,原因上面已解释。

                        ​​ 

03-代码

01-主函数

        用于测试二叉排序树的创建、查找、删除。

        其中创建、查找使用了两种方式实现。一种是非递归形式(for循环),另一种是递归形式。

#include "./Head/BinarySearchTreeData.h"
#include "./Source/BinarySearchTreeCommon.cpp"
#include "./Source/BinarySearchTreeFunction.cpp"

int main() {
    // 创建
    BinaryTree BST = NULL;
    int data[7] = {54, 20, 66, 40, 28, 79, 58};
    int Length = 7;
    BinarySearchTreeCreate(BST, data, Length);
    InOrderTraversalTree(BST); // 有小到大
    printf("\n");

    // 查找
    BinaryTree OutputTree;
    OutputTree = BinarySearchTreeSearch(BST, 66);
    if (OutputTree) {
        printf("Value = %d\n", OutputTree->data);
    } else {
        printf("Not Find.\n");
    }

    // 递归创建
    BinaryTree BST1 = NULL;
    BinarySearchTreeRecursionCreate(BST1, data, Length);
    InOrderTraversalTree(BST1); // 有小到大
    printf("\n");

    // 查找
    OutputTree = BinarySearchTreeRecursionSearch(BST1, 66);
    if (OutputTree) {
        printf("Value = %d\n", OutputTree->data);
    } else {
        printf("Not Find.\n");
    }

    // 删除
    BinarySearchTreeRecursionDelete(BST, 66);
    InOrderTraversalTree(BST);
    printf("\n");
    return 0;
}

02-头文件

        用于存储结构体和常量等。

//
// Created by 24955 on 2023-03-04.
//

#ifndef INC_03_BINARYSEARCH_SORT_TREE_BINARYSEARCHTREEDATA_H
#define INC_03_BINARYSEARCH_SORT_TREE_BINARYSEARCHTREEDATA_H
// 头文件
#include <stdio.h>
#include <stdlib.h>

// 常量
typedef int ElemType;

// 结构体
typedef struct BinaryTreeNode {
    ElemType data;
    struct BinaryTreeNode *lChild, *rChild;
} BinaryTreeNode, *BinaryTree;
#endif //INC_03_BINARYSEARCH_SORT_TREE_BINARYSEARCHTREEDATA_H

03-BinarySearchTreeCommon.cpp

        用于存储二叉排序树打印函数(中序遍历--为有序排列,从小到大)。

//
// Created by 24955 on 2023-03-04.
//
// 中序遍历
void InOrderTraversalTree(BinaryTree BTree) {
    /*
     * 1. 左、自身、右*/
    if (BTree != NULL) {
        InOrderTraversalTree(BTree->lChild);
        printf("%3d", BTree->data);
        InOrderTraversalTree(BTree->rChild);
    }
}

04-BinarySearchTreeFunction.cpp

        用于存储二叉排序树创建、查找、删除等函数。

//
// Created by 24955 on 2023-03-04.
//
// 二叉排序树插入结点
void BinarySearchTreeInsert(BinaryTree &BST, ElemType value) {
    /*
     * 1. 初始化新结点
     * 2. 判断是否为根节点
     * 3. 不为根节点比较两节点数值大小决定插入位置*/
    // 初始化新结点
    BinaryTree NewNode = (BinaryTree) calloc(1, sizeof(BinaryTreeNode));
    NewNode->data = value;
    // 循环树结点标签
    BinaryTree BSTLabel = BST;
    if (BST == NULL) {
        BST = NewNode;
    } else {
        // 插入结点
        while (BSTLabel) {
            if (BSTLabel->data > value) {
                if (BSTLabel->lChild == NULL) {
                    BSTLabel->lChild = NewNode;
                    break;
                } else {
                    BSTLabel = BSTLabel->lChild;
                }
            } else {
                if (BSTLabel->rChild == NULL) {
                    BSTLabel->rChild = NewNode;
                    break;
                } else {
                    BSTLabel = BSTLabel->rChild;
                }
            }
        }
        // 或者采用以下代码(用空间减少循环中判断,即换时间)
        /*
         BinaryTree BSTLabelParent;
         while (BSTLabel) {
            BSTLabelParent = BSTLabel;
            if (BSTLabel->data > value) {
                BSTLabel = BSTLabel->lChild;
            } else { // 不用考虑相等情况,408中未考过存在相同值的情况
                BSTLabel = BSTLabel->rChild;
            }
         }
         if (BSTLabelParent->data > value){
            BSTLabelParent->lChild = NewNode;
         } else {
            BSTLabelParent->rChild = NewNode;
         }
         */
    }
}

// 创建二叉排序树
void BinarySearchTreeCreate(BinaryTree &BST, const ElemType data[], int Length) {
    /*
     * 1. 初始化树根
     * 2. 按数据值大小插入树*/
    // const是C语言的一种关键字,它所限定的变量是不允许被改变的
    // 树根
    BST = NULL;
    for (int i = 0; i < Length; i++) {
        BinarySearchTreeInsert(BST, data[i]);
    }
}

// 二叉排序树查找(也可以采用递归方式)
BinaryTree BinarySearchTreeSearch(BinaryTree BST, ElemType value) {
    /*
     * 1. 判断根节点值是否与待查找值相等
     * 2. 若相等返回根结点地址
     * 3. 若不相等判断是否大于当前结点值若小于BST = BST->lChild;反之大于BST = BST->rChild;
     * 4. 若未查到返回NULL*/
    while (BST) {
        if (BST->data == value) {
            return BST;
        } else if (BST->data > value) {
            BST = BST->lChild;
        } else {
            BST = BST->rChild;
        }
    }
    return NULL;
}

/*************************** 以下为递归方式实现 *******************************/
// 递归方法插入树新结点
void BinarySearchTreeRecursionInsert(BinaryTree &BST, ElemType value) {
    /*
     * 1. 判断当前结点是否为空
     * 2. 若为空插入
     * 3. 若不为空判断大小,进行递归*/
    if (BST == NULL) {
        // 初始化新结点
        BinaryTree NewNode = (BinaryTree) calloc(1, sizeof(BinaryTreeNode));
        NewNode->data = value;
        BST = NewNode;
    } else {
        if (BST->data > value) {
            BinarySearchTreeRecursionInsert(BST->lChild, value);
        } else {
            BinarySearchTreeRecursionInsert(BST->rChild, value);
        }
    }
}

// 调用递归插入函数创建二叉排序树
void BinarySearchTreeRecursionCreate(BinaryTree &BST, const ElemType data[], int Length) {
    /*
     * 1. 初始化树根
     * 2. 按数据值大小插入树*/
    // const是C语言的一种关键字,它所限定的变量是不允许被改变的
    // 树根
    BST = NULL;
    for (int i = 0; i < Length; i++) {
        BinarySearchTreeRecursionInsert(BST, data[i]);
    }
}

void BinarySearchTreeRecursionDelete(BinaryTree &BST, ElemType value) {
    /*
     * 1. 若删除元素值比当前元素值小,递归传入左孩子
     * 2. 若删除元素值比当前元素值大,递归传入右孩子
     * 3. 若相等,则判断当前元素左、右孩子是否为空
     * 4. 若其中任意一个为空,则将另一个替代要当前元素(要删除元素)
     * 5. 若都不为空,循环寻找当前元素左子树中最大值,替代当前元素值,并删除左子树中用于替代的结点*/
    // 防止输入的为树中未包含元素,无法停止递归
    if (BST == NULL) {
        return;
    }
    if (BST->data > value) {
        BinarySearchTreeRecursionDelete(BST->lChild, value);
    } else if (BST->data < value) {
        BinarySearchTreeRecursionDelete(BST->rChild, value);
    } else {
        BinaryTree FreeNode;
        // 若左、右孩子其中任意一个为空,则将另一个替代要当前元素(要删除元素)
        if (BST->lChild == NULL) {
            FreeNode = BST;
            BST = BST->rChild;
            free(FreeNode);
        } else if (BST->rChild == NULL) {
            FreeNode = BST;
            BST = BST->lChild;
            free(FreeNode);
        } else {
            // 左、右孩子都不为空
            // 一般删除策略为:左子树的最大数据 或 右子树的最小数据,替代要删除的结点
            // 此处采用左子树的最大数据
            BinaryTree TemporaryTree = BST->lChild;
            // 寻找左子树中的最大值
            while (TemporaryTree->rChild) {
                TemporaryTree = TemporaryTree->rChild;
            }
            // 替代,删除替代结点
            BST->data = TemporaryTree->data;
            // 此处注意不要传入TemporaryTree
            // 经单点调试发现,传入TemporaryTree会造成乱码(未将叶子结点设为NULL)
            BinarySearchTreeRecursionDelete(BST->lChild, TemporaryTree->data);
        }
    }
}

// 二叉排序树查找-递归方式
BinaryTree BinarySearchTreeRecursionSearch(BinaryTree BST, ElemType value) {
    /*
     * 1. 返回值为NULL或所查找到的结点*/
    if (BST != NULL && BST->data != value) {
        if (BST->data > value) {
            BST = BinarySearchTreeRecursionSearch(BST->lChild, value);
        } else {
            BST = BinarySearchTreeRecursionSearch(BST->rChild, value);
        }
    }
    return BST;
}

结语

        此博客主要用于408考研数据结构C语言实现记录,内有不足,可留言,可讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/388184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于支持向量机SVM的房价预测,基于支持向量机SVM的回归分析

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 SVM应用实例,基于SVM的房价预测 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大的线性分类器,间隔最大使它有别于感知机;…

【算法题】1958. 检查操作是否合法

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个下标从 0 开始的 8 x 8 网…

Vue响应式原理————Object.defineProperty()和proxy的用法分享

Vue框架一个比较核心的功能就是我们的数据是响应式的&#xff0c;这样我们在修改数据的时候&#xff0c;页面会自动帮我们更新&#xff0c;那么想要实现这个功能就要实现对一个数据的劫持&#xff0c;即在取值和设置值的同时我们能够检测到即数据劫持。vue2响应式的实现原理所依…

用原生js手写分页功能

分页功能如下&#xff1a; 数据分页显示&#xff0c;每页显示若干条数据&#xff0c;默认当前页码为第一页。例如&#xff1a;每页5条数据&#xff0c;则第一页显示 1-5 条&#xff0c;第二页显示 6-10 条&#xff0c;依此类推。当页码为第一页时&#xff0c;上一页为禁用状态…

IronPDF for .NET 2023.2.4 Crack

适用于 .NET 2023.2.4 的 IronPDF 添加对增量 PDF 保存的支持。 2023 年 3 月 2 日 - 10:23新版本 特征 添加了对 IronPdfEngine Docker 的支持。 添加了对增量 PDF 保存的支持。 重新设计了 PDF 签名和签名。 删除了 iTextSharp 依赖项。 在文本页眉/页脚中添加了 DrawDivider…

laravel8多模块、多应用和多应用路由

1、安装多应用模块 composer require nwidart/laravel-modules2、执行命令&#xff0c;config文件夹下生成一个modules.php配置文件 php artisan vendor:publish --provider"Nwidart\Modules\LaravelModulesServiceProvider"3、修改config文件夹下的modules.php&am…

python爬虫学习之路

【2023.3.3】一、爬虫概念 通过编写程序&#xff0c;模拟浏览器上网&#xff0c;然后让其去互联网上抓取数据的过程。 价值&#xff1a; 抓取互联网上的数据&#xff0c;为我所用&#xff0c;有了大量的数据&#xff0c;就如同有了一个数据银行一样&#xff0c;下一步做的就是如…

程序员怎么写出亮眼的简历?

要随时与正能量的人保持同行&#xff0c;因为他的心一直在靠近远方 什么是简历 我们先看下百度百科对于简历的描述&#xff1a; 可以看出&#xff0c;简历是受法律规定&#xff0c;因为简历本身的信息真实性较高&#xff0c;所以简历一直是早期被市场上进行数据交易的重要载…

windows 下 python 和repo 下载安装环境变量配置

repo 安装成功&#xff0c;但是下载代码 repo init的时候出错 不知道是不是repo windows版本有问题 python 最好下载2.6-2.7版本的 Python Releases for Windows | Python.org 不然下载代码会有问题&#xff0c;下不了&#xff0c;会提示安装2.6-2.7版本的 Windows下成功安…

人机界面艺术设计

人机界面艺术设计 2.1人机界面艺术设计思路 人们经常有意通过某种工具或创造来解决难题&#xff0c;然而这并不意味着人们乐于接受别人或其他事情&#xff0c;他们很难提出问题。在用户使用网页或软件的时候&#xff0c;他们有明确的目标&#xff0c;他们利用电脑来帮助自己达…

Hbase RegionServer的核心模块

RegionServer是HBase系统中最核心的组件&#xff0c;主要负责用户数据写入、读取等基础操作。RegionServer组件实际上是一个综合体系&#xff0c;包含多个各司其职的核心模块&#xff1a;HLog、MemStore、HFile以及BlockCache。 一、RegionServer内部结构 RegionServer是HBas…

Altium Designer PCB孤岛铜的去除方法教程

孤岛铜&#xff0c;也叫死铜&#xff0c;是指在PCB中孤立无连接的铜箔&#xff0c;一般都是在敷铜的时候产生&#xff0c;不利于生产。解决的办法比较简单&#xff0c;可以手工连线将其与同网络的铜箔相连&#xff0c;也可以通过打过孔的方式将其与同网络的铜箔相连。无法解决的…

Biomod2 (下):物种分布模型建模

这里写目录标题1.给出一个线性回归模型并求出因子贡献度2.biomod22.1 pseudo-absences:伪不存在点&#xff08;PA&#xff09;2.1.1 random2.2.2 disk2.2.3 user.defined method3.使用网格划分区域3.1 计算质心4. 完整案例1.给出一个线性回归模型并求出因子贡献度 ##---------…

【游戏逆向】FPS游戏玩家对象数据分析

玩家健康值 查找玩家健康值,玩家健康值是100,但是我们并不知道数值类型,我们可以使用精确搜索方式搜索100-所有类型 CE搜索 结果很多,我们可以使用手雷来减少血量 我们会得到两个结果 我们可以去尝试改变数值,最终发现一个是我们的客户端健康值,一个是服务器健康值,…

Java——N皇后问题

题目链接 leetcode在线oj题——N皇后 题目描述 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff…

RocketMQ Broker消息处理流程剩余源码解析

&#x1f34a; Java学习&#xff1a;Java从入门到精通总结 &#x1f34a; 深入浅出RocketMQ设计思想&#xff1a;深入浅出RocketMQ设计思想 &#x1f34a; 绝对不一样的职场干货&#xff1a;大厂最佳实践经验指南 &#x1f4c6; 最近更新&#xff1a;2023年3月4日 &#x1…

CCNP350-401学习笔记(补充题目1-100)

1、wireless client to roam --->> wireless client 2、Cisco aWIPS policies on the WLC 3、 import json -->> while true -->>except -->> File open -->>File.close() -->> File.open() 4、 login console group radius 5、undesir…

大数据框架之Hadoop:MapReduce(七)MapReduce扩展案例

一、倒排索引案例&#xff08;多job串联&#xff09; 1、需求 有大量的文本&#xff08;文档、网页&#xff09;&#xff0c;需要建立搜索索引&#xff0c;如图4-31所示。 &#xff08;1&#xff09;数据输入 &#xff08;2&#xff09;期望输出数据 atguigu c.txt–>2…

VS2022+Qt5.14.2成功编译MITK2022.10

目录 一 编译结果 二 编译问题解决 三 参考链接 一 编译结果 二 编译问题解决 error C2220错误 1> mitkSlicedGeometry3D.cpp 1>D:\MITK\src\MITK-2022.10\Modules\Core\src\DataManagement\mitkSlicedGeometry3D.cpp(1,1): error C2220: 以下警告被视为错误 [D:\MI…

能代替try catch处理异常的优雅方式

前言软件开发过程中&#xff0c;不可避免的是需要处理各种异常&#xff0c;就我自己来说&#xff0c;至少有一半以上的时间都是在处理各种异常情况&#xff0c;所以代码中就会出现大量的try {…} catch {…} finally {…} 代码块&#xff0c;不仅有大量的冗余代码&#xff0c;而…