C语言基础(二十六)

news2024/9/22 12:48:52

二叉树节点通常包含三个部分:存储数据的部分、指向左子节点的指针、以及指向右子节点的指针。

测试代码:

#include "date.h" 
#include <stdio.h>  
#include <stdlib.h>  
#include <time.h> 
// 定义二叉树节点的结构,包括节点的值、指向左子节点的指针和指向右子节点的指针。
typedef struct TreeNode {  
    int value;  
    struct TreeNode *left;  
    struct TreeNode *right;  
} TreeNode;  
// 创建一个新的树节点,并分配内存。如果内存分配失败,则打印错误信息并退出程序。 
TreeNode* createNode(int value) {  
    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));  
    if (newNode == NULL) {  
        printf("Memory allocation failed\n");  
        exit(1);  
    }  
    newNode->value = value;  
    newNode->left = NULL;  
    newNode->right = NULL;  
    return newNode;  
}  
  
// 递归调用:将新值插入到二叉搜索树中的适当位置。
// 如果根节点为空,则新节点成为根节点;
// 如果新值小于根节点的值,则递归地在左子树中插入;
// 如果新值大于或等于根节点的值,则递归地在右子树中插入。
// 插入规则由程序员决定。、 
void insertNode(TreeNode** root, int value) {  
    if (*root == NULL) {  
        *root = createNode(value);  
    } else if (value < (*root)->value) {  
        insertNode(&((*root)->left), value);  
    } else {  
        insertNode(&((*root)->right), value);  
    }  
}  
// 递归调用:打印二叉树的内容,同时根据节点的层级打印相应数量的空格,可视化树的形状。  
void printTree(TreeNode* root, int level) {  
    if (root == NULL) return;  
  
    // 打印空格以显示树的层级  
    for (int i = 0; i < level; i++) {  
        printf("   ");  
    }  
    printf("%d\n", root->value);  
  
    // 递归打印左子树和右子树,层级+1  
    printTree(root->left, level + 1);  
    printTree(root->right, level + 1);  
}  
  
int generateRandomNumber(int min, int max) {   
    return min + rand() % (max - min + 1);  
} 
 
void freeTree(TreeNode* root) {  
    if (root != NULL) {  
        // 递归调用释放左子树  
        freeTree(root->left);  
        // 递归调用释放右子树  
        freeTree(root->right);  
        // 释放当前节点  
        free(root);  
    }  
}  
int main() {  

    int times = getTime();
    // 创建一个空的二叉搜索树,并随机插入一系列值。 
    TreeNode* root = NULL; // 初始化为空树  
    srand(time(NULL)); // 设置随机数生成的种子  
    // 插入随机生成的节点  
    for (int i = 0; i < 8; i++) {  
        int randomValue = generateRandomNumber(1, 100); // 生成1到100之间的随机数  
        insertNode(&root, randomValue);  
        printf("Inserted: %d\n", randomValue);  
    }  
  
    // 打印二叉树  
    printTree(root, 0);  
    // 动态释放内存   
    freeTree(root); 
    
    return 0;  
}

运行结果如下:

 

..........................................................................................................................................................

AVL树是一种自平衡的二叉搜索树,其中每个节点的两个子树的高度最大差别为1,其平衡因子(左子树高度减右子树高度)的绝对值不超过1。在AVL树中进行插入或删除节点后,会破坏树的平衡。为了恢复平衡,需要执行一种或多种旋转操作(单旋转或双旋转)。

测试代码:

#include "date.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// AVL树 
// 定义结构体 
typedef struct TreeNode {
    int value;
    struct TreeNode *left;
    struct TreeNode *right;
} TreeNode;
// 定义函数createNode,创建新节点并返回指向该节点的指针。
// 如果内存分配失败,则打印错误信息并退出程序。 
TreeNode* createNode(int value) {
    TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
    if (newNode == NULL) {
        printf("Memory allocation failed:\n");
        exit(1);
    }
    newNode->value = value;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}
// 定义函数rotateRight,用于向右旋转二叉树节点。
// 将当前节点的左孩子作为新的根节点,调整左右孩子的指向。 
void rotateRight(TreeNode** root) {
    TreeNode* newRoot = (*root)->left;
    (*root)->left = newRoot->right;
    newRoot->right = *root;
    *root = newRoot;
}
// 定义函数rotateLeft,用于向左旋转二叉树节点。
// 将当前节点的右孩子作为新的根节点,调整左右孩子的指向。 
void rotateLeft(TreeNode** root) {
    TreeNode* newRoot = (*root)->right;
    (*root)->right = newRoot->left;
    newRoot->left = *root;
    *root = newRoot;
}
// 定义函数getHeight,用于计算树的高度。
// 递归调用比较左右子树的高度并返回较大值加1: 
int getHeight(TreeNode* root) {  
    if (root == NULL) return 0;  
    return 1 + (getHeight(root->left) > getHeight(root->right) ? getHeight(root->left) : getHeight(root->right));  
} 
// 定义函数rebalance,用于平衡二叉树。
// 通过比较左右子树的高度差来判断是否需要旋转,然后执行相应的旋转操作。 
void rebalance(TreeNode** root) {
    if (*root == NULL) {
        return;
    }
    int leftHeight = getHeight((*root)->left);
    int rightHeight = getHeight((*root)->right);

    if (leftHeight - rightHeight > 1) {
        if (getHeight((*root)->left->left) < getHeight((*root)->left->right)) {
            rotateLeft(&((*root)->left));
        }
        rotateRight(root);
    } else if (rightHeight - leftHeight > 1) {
        if (getHeight((*root)->right->right) < getHeight((*root)->right->left)) {
            rotateRight(&((*root)->right));
        }
        rotateLeft(root);
    }
}
// 定义函数insertNode,用于向树中插入新节点。
// 根据值的大小递归调用,在左右子树中插入节点,并在插入后执行平衡操作。 
void insertNode(TreeNode** root, int value) {
    if (*root == NULL) {
        *root = createNode(value);
    } else if (value < (*root)->value) {
        insertNode(&((*root)->left), value);
    } else {
        insertNode(&((*root)->right), value);
    }
    rebalance(root);
}
// 定义函数printTree,用于按层次打印树。
// 递归调用打印节点值,并通过增加缩进表示树的层次结构。 
void printTree(TreeNode* root, int level) {
    if (root == NULL) return;

    for (int i = 0; i < level; i++) {
        printf("   ");
    }
    printf("%d\n", root->value);

    printTree(root->left, level + 1);
    printTree(root->right, level + 1);
}
// 定义函数generateRandomNumber,用于生成介于[min, max]范围内的随机数。 
int generateRandomNumber(int min, int max) { 
    return min + rand() % (max - min + 1);
}
// 定义函数freeTree,用于释放树的内存。
// 递归调用释放左右子树的内存,并释放根节点的内存。 
void freeTree(TreeNode* root) {
    if (root != NULL) {
        freeTree(root->left);
        freeTree(root->right);
        free(root);
    }
}
// 初始化根节点为NULL,然后随机数生成15个介于1和100之间的值,并插入到树中。
// 插入后打印树结构,并最后释放树的内存。 
int main() {
    int times = getTime();

    TreeNode* root = NULL;
    srand(time(NULL));

    for (int i = 0; i < 15; i++) {
        int randomValue = generateRandomNumber(1, 100);
        insertNode(&root, randomValue);
        printf("Inserted: %d\n", randomValue);
    }
    printTree(root, 0);
    freeTree(root);
   }

运行结果如下:

 

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

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

相关文章

Linux虚拟机搭建K8S环境

文章目录 一、环境准备二、系统初始化三、部署master四、添加node节点五、部署网络六、部署dashboard七、登录dashboard面板 一、环境准备 首先在vmware上新建4台相同配置的虚拟机&#xff0c;除了IP和主机名外&#xff0c;其余配置相同。由于是搭建K8S初始环境&#xff0c;没…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

一、多线程任务和多窗体交互 【main】 import MainForm #import CRUD import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBoxif __name__ __main__:app QApplication(sys.argv)MainWindow QMainWindow()ui MainForm.Ui_MainWindow()#也可能是Ui…

算法设计与分析:实验三 回溯法——地图填色问题

实验内容与要求&#xff1a; 问题描述&#xff1a; 我们可以将地图转换为平面图&#xff0c;每个地区变成一个节点&#xff0c;相邻地区用边连接&#xff0c;我们要为这个图形的顶点着色&#xff0c;并且两个顶点通过边连接时必须具有不同的颜色。附件是给出的地图数据&#…

如何在 MySQL 中使用 Socket 身份验证 ?

在 MySQL 和 MariaDB 中&#xff0c;可以使用 socket 身份验证&#xff0c;而不是传统的用户名和密码组合。这种方法既安全又方便&#xff0c;因为它使用的是操作系统的用户凭证。 什么是 Socket 身份验证? Socket 身份验证允许使用 Unix 或 Linux 用户凭证连接到数据库&…

NS4892B 蓝牙耳机充电仓-线性锂电池充放电管理 IC

1 特性 充电部分  (0V) 涓流 / 恒流 / 恒压三段式充电  内部设定 300mA 充电电流  线性工作模式充电  内置自动复充功能  内部预设 4.2V 充电浮充电压  内置过温保护 放电部分  同步升压输出 5.1V  放电开关频率 1MHz  放电效率最…

【网络】NAT、代理服务、内网穿透

NAT技术与代理服务 文章目录 1.NAT技术1.1NAT技术背景1.2NAT IP转换过程1.3NAPT1.4NAT技术的缺陷 2.代理服务器3.NAT和代理服务器的区别4.内网穿透 1.NAT技术 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;技术&#xff0c;是解决IP地址不…

高效处理高并发手机号查询请求:系统设计与优化策略

高效处理高并发手机号查询请求&#xff1a;系统设计与优化策略 一、系统架构设计原理1. 路由网关层2. Web服务层3. 消息队列层4. 实时查询微服务层5. 缓存预热服务 二、总结与优化 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在现代互联…

Java语言程序设计基础篇_编程练习题17.14 (加密文件)/17.15 (解密文件)

题目&#xff1a;17.14 (加密文件) 通过给文件中的每个字节加5来对文件编码。编写一个程序&#xff0c;提示用户输入一个输入文件名和一个输出文件名&#xff0c;然后将输入文件的加密版本存入输出文件。 代码示例&#xff1a;编程练习题17_14EncryptFiles.java package chapte…

VM Workstation虚拟机AlmaLinux 9.4操作系统安装(桌面版安装详细教程)(宝塔面板的安装),填补CentOS终止支持维护的空白

目录 AlmaLinux介绍 AlmaLinux操作系统的安装 1、下载镜像文件 2、新建虚拟机 &#xff08;1&#xff09;点击创建新的虚拟机 &#xff08;2&#xff09;打开虚拟机向导后&#xff0c;选择“自定义”安装&#xff0c;然后点击“下一步” &#xff08;3&#xff09;选择虚…

文本数据分析-(TF-IDF)(1)

文章目录 一、TF-IDF简介1.意义2.TF与IDF1).TF&#xff08;Term Frequency&#xff09;2).IDF&#xff08;Inverse Document Frequency&#xff09;3).TF-IDF 二、应用三、代码实现1.文件读取2.数据预处理3.排序和输出4.全部代码 一、TF-IDF简介 1.意义 TF-IDF&#xff08;Te…

大数据查询优化之谓词下推 ?

谓词 谓词&#xff0c;可以理解为条件表达式&#xff0c;在SQL中&#xff0c;谓词就是返回Boolean值&#xff0c;即True或False的函数&#xff0c;或是隐式转换为Boolean的函数。SQL中的谓词主要有 LKIE、BETWEEN、IS NULL、IS NOT NULL、IN、EXISTS其结果为布尔值&#xff0c…

NASA数据集:ASO L4雷达雪神数据集

目录 简介 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ASO L4 Lidar Snow Depth 50m UTM Grid V001 简介 该数据集包含根据机载光探测和测距仪&#xff08;或称激光雷达&#xff09;对地表高程的测量得出的 50 米网格雪深。 这些数据是 NASA/JPL 机载雪地观测…

如何构建基于Java SpringBoot的医疗器械管理系统?四步详解从需求分析到系统部署,集成Vue.js提升用户体验,内含MySQL数据库管理技巧。

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

采购管理流程:自动化如何使效率提升75% ?

与许多业务流程一样&#xff0c;采购到付款 (P2P) 流程也面临着潜在错误、可避免的成本支出以及可能导致的延误。目前&#xff0c;实现自动化的采购流程比例尚不足一半。 自动化在工作场所的应用具有深远的影响&#xff0c;其重要性不言而喻。对于某些企业而言&#xff0c;自动…

android openGL ES详解——面剔除

一、什么是面剔除&#xff1f; 1.面剔除 尝试在头脑中想象一下有一个3D立方体&#xff0c;你从任何一个方向去看它&#xff0c;最多可以同时看到多少个面。如果你的想象力不是过于丰富&#xff0c;你最终最多能数出来的面是3个。你可以从一个立方体的任意位置和方向上去看它&…

金融上云方案中,国产虚拟化产品选型的重点考虑因素、自动化运维建设步骤及如何进行保障数据中心安全需求的存储设计等问题及解决方法|金融行业数字化QA合集③

Q&#xff1a;金融机构应该从哪些方面考虑虚拟化产品选型&#xff1f; 我行是中小规模城商行&#xff0c;想实现虚拟化国产替换&#xff0c;针对国产虚拟化种类繁多的情况&#xff0c;我行应该从哪些方面考虑产品选型&#xff0c;确保所选择产品既能满足信创替换&#xff0c;又…

银河麒麟v10-sp3-x86系统安装k8s-1.30.4

X86-64和arm架构的区别 x86-64架构&#xff1a; 设计理念&#xff1a;x86-64架构起源于Intel的x86架构&#xff0c;并对其进行了64位扩展。这种架构的设计侧重于高性能和灵活性&#xff0c;适合处理复杂的计算任务。 性能特点&#xff1a;x86-64架构的处理器通常提供高性能的…

六个方面探讨企业为何迫切需要替换FTP

随着信息技术的迅猛发展和网络安全形势的日趋严峻&#xff0c;传统的FTP文件传输协议因其固有的局限性和安全隐患&#xff0c;逐渐难以满足现代企业的需求。因此&#xff0c;寻找并升级FTP替代方案成为众多企业需要解决的问题。本文将从六个方面探讨企业为何迫切需要替换FTP。 …

云轴科技ZStack产品升级,浙江分公司产品发布会成功举办

近日&#xff0c;以“智启未来&#xff0c;云端共赢”为主题的云轴科技ZStack浙江分公司针对浙江地区渠道合作伙伴的产品发布会在杭州顺利召开。ZStack总代理伟仕佳杰、神州数码、英迈等百余位合作伙伴代表出席会议&#xff0c;共同见证ZStack在云基础设施与AI软件基础设施领域…

易查分如何查询图片?

最近经常看到老师们各种分享和讨论一个问题&#xff0c;今天&#xff0c;我就和大家聊聊如何高效地在易查分平台上上传和管理图片&#xff0c;让查询结果更加直观。 首先准备你的图片&#xff0c;无论是获奖证书还是奖状&#xff0c;确保它们的格式正确&#xff0c;比如"2…