数据结构-非线性结构-二叉树

概述

/**

 * 术语

 * 根节点(root node):位于二叉树顶层的节点,没有父节点。

 * 叶节点(leaf node):没有子节点的节点,其两个指针均指向 None 。

 * 边(edge):连接两个节点的线段,即节点引用(指针)。

 * 节点所在的层(level):从顶至底递增,根节点所在层为 1 。

 * 节点的度(degree):节点的子节点的数量。在二叉树中,度的取值范围是 0、1、2 。

 * 二叉树的高度(height):从根节点到最远叶节点所经过的边的数量。

 * 节点的深度(depth):从根节点到该节点所经过的边的数量。

 * 节点的高度(height):从距离该节点最远的叶节点到该节点所经过的边的数量。

 */

/**

 * 二叉树遍历:【前序、中序、后序】->【递归遍历实现、非递归遍历实现(栈实现)】、层次遍历(队列实现)

 * 二叉查找树:具有性质如下的二叉树:对于任一结点,如果它包含的数据元素为data,

 *     那么它的左子树(如果非空)只包含小于data的元素,并且它的右子树(如果非空)只包含大于或等于data的元素。

 *     中序遍历二叉查找树将会得到从小到大排列的结点序列。

 * 二叉线索树:通过利用原本指向空子节点(即 NULL 指针)的空间来指向前驱或后继节点,从而在遍历时不需要使用额外的栈或递归。

 *     这种结构特别适用于那些需要频繁遍历而修改较少的应用场景。

 * 平衡二叉树:AVL树、红黑树

 *     关键特性:左右子树高度差的绝对值不超过1

 * 完全二叉树:主要用于实现堆(最大堆、最小堆)、哈夫曼编码

 *     关键特性:按层次填充,每一层(除了最后一层)都完全填满,最后一层从左到右依次填充,没有间断

 * 满二叉树:一种特殊的二叉树,每一层的节点都完全填满的二叉树

 */

/**

 * 递归遍历

 * 前序遍历:访问顺序为“根-左-右”。即先访问根节点,然后依次递归遍历左子树和右子树。

 * 中序遍历:访问顺序为“左-根-右”。即先递归遍历左子树,然后访问根节点,最后递归遍历右子树。

 * 后序遍历:访问顺序为“左-右-根”。即先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

 */

/**

 * 红黑树

 * 红黑树的一些基本特性和规则:

 * 每个节点要么是红色,要么是黑色。

 * 根节点是黑色。

 * 所有叶子节点(NIL节点,通常不显示在图中)都是黑色的。

 * 如果一个节点是红色,则它的两个子节点都是黑色(即不能有两个连续的红色节点)。

 * 从任一节点到其每个叶子的所有路径都包含相同数量的黑色节点。

 */

 // 难点:遍历、旋转、删除

common.h

#pragma once#define TRUE 1
#define FALSE 0// 定义节点数据类型
#define DATA_TYPE int

二叉树插入、删除、递归遍历

BinaryTree.h

#pragma once#include "common.h"typedef struct Node
{DATA_TYPE data;struct Node *left;struct Node *right;
} Node;// 创建一个树结点
static Node *newBinaryTreeNode(DATA_TYPE data)
{Node *node = malloc(sizeof(Node));node->data = data;node->left = NULL;node->right = NULL;return node;
}// 旋转节点使二叉树平衡
Node *rotate(Node *node);// 向二叉树插入数据 平衡化重构
Node *insertNode(Node *T, DATA_TYPE data); // 递归void insertNode_root(DATA_TYPE data); // 插入、从root开始
void insertData(DATA_TYPE data);           // 迭代 不会选择平衡化// 返回二叉树结点数
int size();// 节点高度
int height(Node *T);// 前序、中序、后序遍历
void preOrder(Node *T);
void inOrder(Node *T);
void postOrder(Node *T);
// 逆中序打印二叉树
void printTree(Node *T, int level);// 判断二叉树是否平衡
int is_balanced(Node *T);// 查找数据是否在二叉树中
int search_val(DATA_TYPE val);// 二叉树的root结点
Node *getRoot();// 删除节点
Node *delete_data(DATA_TYPE val);// 清空二叉树
void clear();void test_binary_tree();

BinaryTree.c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>#include "BinaryTree.h"#define MAX_LINE 1024 // 定义二叉树每行包含节点的最大个数 2的指数static Node *root = NULL;
static int node_size = 0;/*********************二叉树平衡化*********************/
// 获取平衡因子
static int balanceFactor(Node *node)
{if (node == NULL){return 0;}return height(node->left) - height(node->right);
}static Node *leftRotate(Node *node)
{Node *right = node->right;node->right = right->left;right->left = node;return right;
}static Node *rightRotate(Node *node)
{Node *left = node->left;node->left = left->right;left->right = node;return left;
}// 旋转节点使二叉树平衡
Node *rotate(Node *node)
{int bf = balanceFactor(node);if (bf > 1) // 左子树{if (balanceFactor(node->left) >= 0) // 左子树{return rightRotate(node);}else{// 先左旋再右旋node->left = leftRotate(node->left);return rightRotate(node);}}else if (bf < -1) // 右子树{if (balanceFactor(node->right) <= 0) // 右子树{return leftRotate(node);}else{node->right = rightRotate(node->right);return leftRotate(node);}}return node;
}
/*********************二叉树平衡化*********************/// 插入数据,迭代方式 不会选择平衡化
void insertData(DATA_TYPE data)
{if (root == NULL){root = malloc(sizeof(Node));root->data = data;root->left = NULL;root->right = NULL;node_size++;return;}Node *node = root;while (node){if (data < node->data){if (node->left == NULL){node->left = malloc(sizeof(Node));node->left->data = data;node->left->left = NULL;node->left->right = NULL;break;}else{node = node->left;}}else{if (node->right == NULL){node->right = malloc(sizeof(Node));node->right->data = data;node->right->left = NULL;node->right->right = NULL;break;}else{node = node->right;}}}node_size++;
}// 插入数据:递归方式 平衡化重构
Node *insertNode(Node *T, DATA_TYPE data)
{if (root == NULL){root = malloc(sizeof(Node));root->data = data;root->left = NULL;root->right = NULL;node_size++;return root;}if (T == NULL){Node *node = malloc(sizeof(Node));node->data = data;node->left = NULL;node->right = NULL;node_size++;return node;}if (data >= T->data){T->right = insertNode(T->right, data);}else{T->left = insertNode(T->left, data);}T = rotate(T);return T;
}void insertNode_root(DATA_TYPE data)
{root = insertNode(root, data);
}void preOrder(Node *T)
{if (T){printf("%d -> ", T->data);preOrder(T->left);preOrder(T->right);}
}
void inOrder(Node *T)
{if (T){inOrder(T->left);printf("%d -> ", T->data);inOrder(T->right);}
}
void postOrder(Node *T)
{if (T){postOrder(T->left);postOrder(T->right);printf("%d -> ", T->data);}
}// 采用逆中序和按层次缩进,是因为把打印结果按顺时针方向旋转90度就能呈现出正常的二叉树形状
void printTree(Node *T, int level)
{if (T){printTree(T->right, level + 1);for (int i = 0; i < level; i++){printf("     ");}printf("%d\n", T->data);printTree(T->left, level + 1);}
}int size()
{return node_size;
}int height(Node *T)
{if (T == NULL){return 0;}return __max(abs(height(T->left)), abs(height(T->right))) + 1;
}static void insertToRoot(DATA_TYPE data)
{insertNode(root, data);
}// 左右子树高度差小于等于1
int is_balanced(Node *T)
{if (T == NULL){return TRUE; // 空树被认为是平衡的}return abs(height(T->left) - height(T->right)) <= 1 && is_balanced(T->left) && is_balanced(T->right);
}static int search(Node *T, DATA_TYPE val)
{while (T){if (T->data == val){return TRUE;}T = (T->data > val) ? T->left : T->right;}return FALSE;
}int search_val(DATA_TYPE val)
{return search(root, val);
}Node *getRoot()
{return root;
}/*********************删除元素*********************/
static Node *deleteLeftmost(Node *T)
{if (T->left == NULL){return T->right;}else{T->left = deleteLeftmost(T->left);return T;}
}static DATA_TYPE getLeftmost(Node *T)
{if (T->left == NULL){return T->data;}else{return getLeftmost(T->left);}
}static Node *deleteTopmost(Node *T)
{if (T->left == NULL){return T->right;}else if (T->right == NULL){return T->left;}else{T->data = getLeftmost(T->right);T->right = deleteLeftmost(T->right);return T;}
}static Node *delete(Node *T, DATA_TYPE val)
{if (T){if (T->data == val){node_size--;return deleteTopmost(T);}else if (val < T->data){T->left = delete(T->left, val);}else{T->right = delete(T->right, val);}}return T;
}Node *delete_data(DATA_TYPE val)
{return delete(root, val);
}void clear()
{free(root);root = NULL;node_size = 0;
}
/*********************删除元素*********************/void test_binary_tree()
{printf("|***********************基础操作***********************|\n");// insertData(4); // root// insertData(2); // root left child// insertData(1); // 2 left child// insertData(3); // 2 right child// insertData(6); // root right child// insertData(5); // 6 left child// insertData(7); // 6 right child// insertToRoot(4); // root// insertToRoot(2); // root left child// insertToRoot(1); // 2 left child// insertToRoot(3); // 2 right child// insertToRoot(6); // root right child// insertToRoot(5); // 6 left child// insertToRoot(7); // 6 right childinsertNode_root(4);insertNode_root(2);insertNode_root(1);insertNode_root(3);insertNode_root(6);insertNode_root(5);insertNode_root(7);insertNode_root(8);insertNode_root(9);insertNode_root(10);insertNode_root(11);insertNode_root(12);// insertNode_root(13);printf("逆中序打印:\n");printTree(root, 0);printf("结点数:%d\n", size());printf("是否包含[%d]:%d\n", 3, search_val(3));printf("是否包含[%d]:%d\n", 9, search_val(9));printf("前序遍历:");preOrder(root);printf("\n");printf("中序遍历:");inOrder(root);printf("\n");printf("后序遍历:");postOrder(root);printf("\n");printf("逆中序打印:\n");printTree(root, 0);printf("\n");int len = height(root);printf("二叉树高度:%d\n", len);printf("二叉树是否平衡:%d\n", is_balanced(root));printf("测试删除元素......");printf("\n");delete_data(4);printf("逆中序打印:\n");printTree(root, 0);printf("\n");delete_data(1);printf("逆中序打印:\n");printTree(root, 0);printf("\n");delete_data(5);printf("逆中序打印:\n");printTree(root, 0);clear();printf("\n");insertNode_root(10);insertNode_root(8);insertNode_root(15);insertNode_root(12);insertNode_root(19);insertNode_root(13); // 先右旋再左旋printf("逆中序打印:\n");printTree(root, 0);printf("|***********************平衡树***********************|\n");
}

二叉树层序遍历

BinaryTreeLevelOrder.h

#include "BinaryTree.h"// 辅助队列节点--用于层序遍历
typedef struct QueueNode
{Node *data;struct QueueNode *next;
} QueueNode;/********************辅助队列方法********************/
int is_queue_empty();
void enQueue(Node *T);
Node *deQueue();
/********************辅助队列方法********************/// 二叉树层序遍历
DATA_TYPE **levelOrder(Node *T, int len /* 有多少层 */);void test_binary_tree_level_order();

BinaryTreeLevelOrder.c

#include <stdio.h>
#include <stdlib.h>#include "BinaryTreeLevelOrder.h"// #define col_len (height(getRoot()))// 层序遍历辅助队列结点数
static int queue_node_size = 0;
static QueueNode *Q = NULL;// 存储二维数组每行有多少个列 即表示二叉树每一层有多少个节点
static int *col;
static int col_len = 0;/********************辅助队列方法********************/
int is_queue_empty()
{return queue_node_size == 0 || Q == NULL;
}
void enQueue(Node *T)
{if (Q == NULL){Q = malloc(sizeof(QueueNode));Q->data = T;Q->next = NULL;queue_node_size++;return;}QueueNode *q_node = Q;while (q_node->next != NULL){q_node = q_node->next;}q_node->next = malloc(sizeof(QueueNode));q_node->next->data = T;q_node->next->next = NULL;queue_node_size++;
}
Node *deQueue()
{Node *val = Q->data;Q = Q->next;queue_node_size--;return val;
}
/********************辅助队列方法********************/DATA_TYPE **levelOrder(Node *T, int len /* 有多少层 */)
{// int (*arr)[MAX_LINE] = malloc(sizeof(*arr) * MAX_LINE);// DATA_TYPE *arr;DATA_TYPE **arr = malloc(sizeof(DATA_TYPE *) * len);col = malloc(sizeof(int) * len);enQueue(T);while (!is_queue_empty()){int curr_queue_size = queue_node_size; // 每行节点个数DATA_TYPE *per_line = malloc(sizeof(DATA_TYPE) * curr_queue_size);int index = 0;for (int i = 0; i < curr_queue_size; i++){Node *n = deQueue();per_line[index++] = n->data;// 从左到右收集节点if (n->left){enQueue(n->left);}if (n->right){enQueue(n->right);}}col[col_len] = index; // 每行有多少列arr[col_len] = per_line;col_len++;}return arr;
}void test_binary_tree_level_order()
{printf("|***********************层序遍历***********************|\n");Node *root = getRoot();int len = height(root);DATA_TYPE **arr = levelOrder(root, len); // 锯齿形数组 需要额外数据结构(数组或链表)保存每行列数// col_len 等于 len 即二叉树的高度 即二叉树有几行for (int i = 0; i < col_len; i++){printf("第%d行有结点数: %d\t", i + 1, col[i]);}printf("\n");for (int i = 0; i < len; i++){int c = col[i];for (int j = 0; j < c; j++){int x = arr[i][j];printf("arr[%d][%d] = %d\t", i, j, x);}printf("\n");}
}

二叉树非递归遍历

BinaryTreeNonRecursiveOrder.h

#include "BinaryTree.h"// 辅助队列节点--用于层序遍历
typedef struct StackNode
{Node *data;struct StackNode *next;
} StackNode;/********************辅助队列方法********************/
int is_stack_empty();
void push(Node *T);
Node *pop();
/********************辅助队列方法********************/// 非递归前序遍历
DATA_TYPE *non_recursive_pre_order(Node *root, int node_size);
// 非递归中序遍历
DATA_TYPE *non_recursive_in_order(Node *root, int node_size);
// 非递归后序遍历
DATA_TYPE *non_recursive_post_order(Node *root, int node_size);void test_binary_tree_non_recursive_order();

BinaryTreeNonRecursiveOrder.c

#include <stdio.h>
#include <stdlib.h>#include "BinaryTreeNonRecursiveOrder.h"static int stack_size = 0;
static StackNode *head = NULL;/********************辅助栈方法********************/static StackNode *newStackNode(Node *T)
{StackNode *node = malloc(sizeof(StackNode));node->data = T;node->next = NULL;return node;
}int is_stack_empty()
{return stack_size == 0;
}
void push(Node *T)
{if (head == NULL){head = newStackNode(T);stack_size++;return;}StackNode *node = newStackNode(T);node->next = head;head = node;stack_size++;
}
Node *pop()
{Node *node = head->data;head = head->next;stack_size--;return node;
}
/********************辅助栈方法********************/DATA_TYPE *non_recursive_pre_order(Node *root, int node_size)
{if (root == NULL){return NULL;}DATA_TYPE *result = malloc(sizeof(DATA_TYPE) * node_size);DATA_TYPE *p = result;while (root || !is_stack_empty()){if (root){*p++ = root->data;push(root);root = root->left;}else{root = pop();root = root->right;}}return result;
}
DATA_TYPE *non_recursive_in_order(Node *root, int node_size)
{if (root == NULL){return NULL;}DATA_TYPE *result = malloc(sizeof(DATA_TYPE) * node_size);DATA_TYPE *p = result;while (root || !is_stack_empty()){if (root){push(root);root = root->left;}else{root = pop();*p++ = root->data;root = root->right;}}return result;
}// 非递归后序遍历
DATA_TYPE *non_recursive_post_order(Node *root, int node_size)
{if (root == NULL){return NULL;}DATA_TYPE *result = malloc(sizeof(DATA_TYPE) * node_size);DATA_TYPE *p = result;Node *pre = NULL;while (root || !is_stack_empty()){while (root){push(root);root = root->left;}root = pop();if (root->right == NULL || root->right == pre){*p++ = root->data;pre = root;root = NULL;}else{push(root);root = root->right;}}return result;
}static void printArray(DATA_TYPE *arr, int len)
{for (int i = 0; i < len; i++){printf("%d -> ", *arr++);}printf("\n");
}void test_binary_tree_non_recursive_order()
{printf("|***********************二叉树非递归遍历***********************|\n");Node *root = getRoot();int len = size(root); // 二叉树结点数 用于动态内存分配时计算长度DATA_TYPE *arr = non_recursive_post_order(root, len);printf("非递归后序遍历:");printArray(arr, len);arr = non_recursive_in_order(root, len);printf("非递归中序遍历:");printArray(arr, len);arr = non_recursive_pre_order(root, len);printf("非递归前序遍历:");printArray(arr, len);
}

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

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

相关文章

芯片笔记 - 手册参数注释

芯片手册参数注释 基础参数外围设备USB OTG&#xff08;On-The-Go&#xff09;以太网存储卡&#xff08;SD&#xff09;SDIO 3.0(Secure Digital Input/Output)GPIO&#xff08;General Purpose Input/Output 通用输入/输出接口&#xff09;ADC&#xff08;Analog to Digital C…

力扣94. 二叉树的中序遍历

94. 二叉树的中序遍历 给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2]示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[]示例 3&#xff1a; 输入&#…

深度学习:AI为老年痴呆患者点亮希望之光

引言 随着全球人口老龄化进程的加速&#xff0c;老年痴呆症已成为严重威胁老年人健康和生活质量的公共卫生问题。据世界卫生组织统计&#xff0c;全球每 3 秒钟就有 1 人被诊断为痴呆&#xff0c;预计到 2050 年&#xff0c;全球痴呆患者人数将从目前的约 5000 万激增至 1.52 亿…

抛物线法(二次插值法)

抛物线法简介 抛物线法&#xff08;Quadratic Interpolation Method&#xff09;是一种用于一维单峰函数极值搜索的经典优化方法。该方法通过在区间内选取三个不同的点&#xff0c;拟合一条二次抛物线&#xff0c;并求取这条抛物线的极值点作为新的迭代点&#xff0c;从而逐步…

FreeRTOS如何检测内存泄漏

在嵌入式系统中&#xff0c;内存资源通常非常有限&#xff0c;内存泄漏可能导致系统性能下降甚至崩溃。内存泄漏是指程序分配的内存未被正确释放&#xff0c;逐渐耗尽可用内存。 FreeRTOS作为一种轻量级实时操作系统&#xff08;RTOS&#xff09;&#xff0c;广泛应用于资源受限…

Mockoon 使用教程

文章目录 一、简介二、模拟接口1、Get2、Post 一、简介 1、Mockoon 可以快速模拟API&#xff0c;无需远程部署&#xff0c;无需帐户&#xff0c;免费&#xff0c;跨平台且开源&#xff0c;适合离线环境。 2、支持get、post、put、delete等所有格式。 二、模拟接口 1、Get 左…

如何进行APP安全加固

进行APP安全加固的关键在于代码混淆、加密敏感数据、权限管理、漏洞扫描与修复。其中&#xff0c;代码混淆能有效阻止逆向工程与篡改攻击&#xff0c;提升应用的安全防护能力。通过混淆代码&#xff0c;攻击者难以轻易理解源代码逻辑&#xff0c;从而降低被破解或攻击的风险。 …

【C++】手搓一个STL风格的string容器

C string类的解析式高效实现 GitHub地址 有梦想的电信狗 1. 引言&#xff1a;字符串处理的复杂性 ​ 在C标准库中&#xff0c;string类作为最常用的容器之一&#xff0c;其内部实现复杂度远超表面认知。本文将通过一个简易仿照STL的string类的完整实现&#xff0c;揭示其设…

辰鳗科技朱越洋:紧扣时代契机,全力投身能源转型战略赛道

国家能源局于4月28日出台的《关于促进能源领域民营经济发展若干举措的通知》&#xff08;以下简称《通知》&#xff09;&#xff0c;是继2月民营企业座谈会后深化能源领域市场化改革的关键政策&#xff0c;标志着民营经济在“双碳”目标引领下正式进入能源转型的核心赛道。 自…

Vue实现不同网站之间的Cookie共享功能

前言 最近有小伙伴在聊天室中提到这么一个需求&#xff0c;就是说希望用户在博客首页中登录了之后&#xff0c;可以跳转到管理系统去发布文章。这个需求的话就涉及到了不同网站之间cookie共享的功能&#xff0c;那么咱们就来试着解决一下这个功能。 实现方式 1. 后端做中转 …

在一台服务器上通过 Nginx 配置实现不同子域名访问静态文件和后端服务

一、域名解析配置 要实现通过不同子域名访问静态文件和后端服务&#xff0c;首先需要进行域名解析。在域名注册商或 DNS 服务商处&#xff0c;为你的两个子域名 blog.xxx.com 和 api.xxx.com 配置 A 记录或 CNAME 记录。将它们的 A 记录都指向你服务器的 IP 地址。例如&#x…

Opencv进阶操作:图像拼接

文章目录 前言一、图像拼接的原理1. 特征提取与匹配2. 图像配准3. 图像变换与投影4. 图像融合5. 优化与后处理 二、图像拼接的简单实现&#xff08;案例实现&#xff09;1.引入库2.定义cv_show()函数3.创建特征检测函数detectAndDescribe()4.读取拼接图片5.计算图片特征点及描述…

LLM 论文精读(三)Demystifying Long Chain-of-Thought Reasoning in LLMs

这是一篇2025年发表在arxiv中的LLM领域论文&#xff0c;主要描述了长思维链 Long Chain-of-Thought 对LLM的影响&#xff0c;以及其可能的生成机制。通过大量的消融实验证明了以下几点&#xff1a; 与shot CoT 相比&#xff0c;long CoT 的 SFT 可以扩展到更高的性能上限&…

计算机网络常识:缓存、长短连接 网络初探、URL、客户端与服务端、域名操作 tcp 三次握手 四次挥手

缓存&#xff1a; 缓存是对cpu&#xff0c;内存的一个节约&#xff1a;节约的是网络带宽资源 节约服务器的性能 资源的每次下载和请求都会造成服务器的一个压力 减少网络对资源拉取的延迟 这个就是浏览器缓存的一个好处 表示这个html页面的返回是不要缓存的 忽略缓存 需要每次…

《构建社交应用用户激励引擎:React Native与Flutter实战解析》

React Native凭借其与JavaScript和React的紧密联系&#xff0c;为开发者提供了一个熟悉且灵活的开发环境。在构建用户等级体系时&#xff0c;它能够充分利用现有的前端开发知识和工具。通过将用户在社交应用中的各种行为进行量化&#xff0c;比如发布动态的数量、点赞评论的次数…

接口自动化测试框架详解(pytest+allure+aiohttp+ 用例自动生成)

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 近期准备优先做接口测试的覆盖&#xff0c;为此需要开发一个测试框架&#xff0c;经过思考&#xff0c;这次依然想做点儿不一样的东西。 接口测试是比较讲究效…

Linux-----文件系统

文件大家都知道&#xff0c;前面的我的博客课程也为大家解释了关于文件的打开等&#xff0c;今天我们要谈论的是 文件在没被打开的时候在磁盘中的位置和找到它的方式。 画图为大家展示&#xff1a; 方便理解 我们从下面几个方面入手&#xff1a; 1. 看看物理磁盘 2. 了解一…

C++ set替换vector进行优化

文章目录 demo代码解释&#xff1a; 底层原理1. 二叉搜索树基础2. 红黑树的特性3. std::set 基于红黑树的实现优势4. 插入操作5. 删除操作6. 查找操作 demo #include <iostream> #include <set>int main() {// 创建一个存储整数的std::setstd::set<int> myS…

如何巧妙解决 Too many connections 报错?

1. 背景 在日常的 MySQL 运维中&#xff0c;难免会出现参数设置不合理&#xff0c;导致 MySQL 在使用过程中出现各种各样的问题。 今天&#xff0c;我们就来讲解一下 MySQL 运维中一种常见的问题&#xff1a;最大连接数设置不合理&#xff0c;一旦到了业务高峰期就会出现连接…

QT的布局和弹簧及其代码解读

this指的是真正的当前正在显示的窗口 main函数&#xff1a; Widget w是生成了一个主窗口&#xff0c;QT Designer是在这个主窗口里塞组件 w.show()用来展示这个主窗口 头文件&#xff1a; namespace Ui{class Widget;}中的class Widget和下面的class Widget不是一个东西 Ui…