数据结构-非线性结构-二叉树
概述
/**
* 术语
* 根节点(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);
}
相关文章:
数据结构-非线性结构-二叉树
概述 /** * 术语 * 根节点(root node):位于二叉树顶层的节点,没有父节点。 * 叶节点(leaf node):没有子节点的节点,其两个指针均指向 None 。 * 边(edge)&…...
Android开发补充内容
Android开发补充内容 fragment通信生命周期 Okhttp基本使用websocket Retrofit基本使用 RxJava基本使用定时任务 Hilt基本使用进阶使用例子 组件库Material ComponentsJetpack Compose fragment 通信 fragment于activity通信的一种原生方法是使用Bundle: Bundle …...
Go主要里程碑版本及其新增特性
Go 语言自 2009 年诞生以来,经历了多个里程碑版本的迭代,每个版本都引入了重要特性和改进。以下是 Go 语言的主要版本及其关键特性: Go 1.0 (2012-03-28) 首个稳定版,承诺向后兼容(Go 1 兼容性保证)。核心…...
Cut video with ffmpeg
To cut a snippet from a video based on timestamps like 02:52 to 04:20, the best tool is FFmpeg, which is fast, free, and doesn’t re-encode the video (so it keeps original quality if you don’t want re-encoding). Here’s the command you can run in a termi…...
无刷电机控制算法策略
目录 一、基础控制算法 二、高性能算法 三、无感算法 四、智能算法 五、特殊场景算法 无刷电机的核心控制算法主要包括以下类型: 一、基础控制算法 六步换向法(梯形控制) 通过霍尔传感器检测转子位置,按固定顺序切换…...
LeetCode算法题(Go语言实现)_61
题目 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金…...
Kafka消息不丢失处理
kafka作为消息中间件,吞吐量大(至于为啥吞吐量大,本文不做介绍),所以大家用的多。涉及到异构数据库更换,以及数据预处理后的迁移,基本想到的都是通过kafka。 概览图 我先画个图 生产者到kafka…...
Python+ffmpeg 实现给视频添加字幕
创作灵感 孩子学校经常留作业,需要提交一段录制的视频,视频上要求添加学校、班级、姓名等信息的字幕,手机自带的相机软件字幕添加位置要么只能添加在视频正中,要么无法添加多行文本,要么只能添加在片头或者片尾&#…...
QMK键盘固件自定义指南 - 打造你的专属键盘体验
QMK键盘固件自定义指南 - 打造你的专属键盘体验 🚀 前言 在机械键盘的世界里,QMK固件让你的键盘不再只是简单的输入设备,而是可以按照你的意愿定制的强大工具。本文将深入浅出地介绍如何自定义QMK键盘的行为,从基础概念到高级应…...
Linux-openeuler更换yum镜像源
将 openEuler 系统镜像源更换为华为镜像 以openEuler 24.03 LTS SP1 为例。操作前建议备份原配置文件,并确保系统已联网。 一、确认系统版本与架构 查看系统版本: [rooteulerzy yum.repos.d]# cat /etc/os-releaseNAME"openEuler"VERSION&qu…...
手势、鼠标滑动实现界面切换
手势: #include <QApplication> #include "mainwindow.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);MainWindow window;window.show();return app.exec(); }#ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainW…...
什么是变量提升?(形象的比喻)
当然!可以用几个生活中的比喻来形象地解释变量提升: 1. 书架的占位符 想象你有一个书架,但还没放书。 • 变量提升(var): 你先在书架上贴了一个标签(比如写“我的书”)&…...
趣味编程:答案之书
概述:该篇博客主要介绍的是曾经一度风靡全网的答案之书小程序。 目录 1. 效果展示 2. 源码展示 3. 代码逻辑详解 3.1 头文件与全局变量 3.2 main函数 3.3 主循环 3. 4 绘制界面 4. 运行问题 5.小结 1. 效果展示 该小程序是动态的效果, 因此实…...
用kompose将docker-compose文件转换为K8S资源清单
一、什么是kompose Kompose 是什么?它是一个转换工具,可将 Compose (即 Docker Compose)所组装的所有内容转换成容器编排器(Kubernetes 或 OpenShift)可识别的形式。 更多信息请参考 Kompose 官网 Kompos…...
Linux中的防火墙
概述 防火墙通过一系列规则来过滤网络数据包,决定哪些数据包可以进入或离开系统,哪些数据包将被阻止,以此来保护系统免受未经授权的访问、恶意攻击和潜在的安全威胁。 常见的防火墙软件 iptables:是 Linux 系统中常用的防火墙工…...
AI开发跃迁指南(第三章:第四维度1——Milvus、weaviate、redis等向量数据库介绍及对比选型)
1.向量数据库简介 向量数据库(Vector Database)是专门为存储和查询高维向量数据而设计的数据库,主要用于处理由机器学习模型生成的嵌入向量(Embeddings)。它在人工智能(AI)、自然语言处理&…...
深度学习笔记41_调用Gensim库训练Word2Vec模型
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 一、我的环境 1.语言环境:Python 3.8 2.编译器:Pycharm 3.深度学习环境: torch1.12.1cu113torchvision…...
Windows Server 2025 安装AMD显卡驱动
运行显卡驱动安装程序,会提示出问题。但是此时资源已经解压 来到驱动路径 C:\AMD\AMD-Software-Installer\Packages\Drivers\Display\WT6A_INF 打开配置文件,把这两行替换掉 %ATI% ATI.Mfg, NTamd64.10.0...16299, NTamd64.10.0, NTamd64.6.0, NTamd64.…...
debian安装docker
debian安装docker <在Debian上安装Docker的步骤》 在Debian上安装Docker通常涉及几个步骤,以确保你能够顺利运行Docker容器。下面是一份详细的指南,帮助你在Debian系统上安装Docker。 1. 更新你的包列表 首先,更新你的包列表以确保所有…...
uniapp上架苹果APP Store踩雷和部分流程注意事项(非完整流程)
本文是uniapp打包成ios上架到苹果商店一系列踩雷和部分流程介绍 1.打包需要俩个证书 需要xx..mobileprovision和xx.p12证书并且ios打包一天最多5次,超出需要2元/1次付费打包,证书需要使用苹果电脑生成,以下为证书生成教程iOS证书(.p12)和描述…...
【吃透 Elasticsearch 的核心原理】学习步骤
要真正,需深入以下关键机制(结合最新技术演进): 一、倒排索引机制 核心三要素 Term Index:FST 结构加速前缀匹配(如 ap* 查询)Term Dictionary:存储所有 token 及统计信息ÿ…...
springboot使用mybatisPlus进行数据库增删改查
springboot使用mybatisPlus进行数据库增删改查 提示:帮帮志会陆续更新非常多的IT技术知识,希望分享的内容对您有用。本章分享的是springboot的使用。前后每一小节的内容是存在的有:学习and理解的关联性。【帮帮志系列文章】:每个…...
移动端前端开发中常用的css
在开发移动端项目的时候,很多样式都是相同的,比如说图标大小,头像大小,页面底部保存(添加按钮),项目主体颜色等等,对于这些在项目中常用到的,通常都会写在公共样式中(pub…...
C/C++内存分布
内存分布示意图: 内存分布各区域详解: 内核空间: 放置操作系统相关的代码和数据。(用户不能直接进行操作 ------ 可以通过调用系统提供的 api 函数) 栈区: 又叫堆栈,非静态局部变量/函数参数/…...
Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
版本: 原因 在 Dart Sass 3.0.0 中, @import 规则将被弃用,推荐使用 @use 和 @forward 规则来替代。 1.@use替代@import @use 规则允许你引入其他 Sass 文件中的变量、混合器和函数,并且可以避免命名冲突。 示例: style.scss @use variables;body {color: variables.$pr…...
【计算机网络】用户从输入网址到网页显示,期间发生了什么?
1.URL解析 浏览器分解URL:https://www.example.com/page 协议:https域名:www.example.com路径:/page 2.DNS查询: 浏览器向DNS服务器发送查询请求,将域名解析为对应的IP地址。 3.CDN检查(如果有)&#…...
使用adb设置wifi相关
其他的可以参考以下指令 Android 使用adb操作WiFi连接扫描等相关指令_adb wifi-CSDN博客 但是如果你的wifi账号出现中文的时候: 例如:ssid "wolf的网络" 这种类型的时候,直接使用adb指令是有问题的,基本都会出现乱码…...
MySQL数据库创建、删除、修改
一:建库建表 我们以学校体系进行建表。将数据库命名为school。 以下代码中的大写均可小写不影响。如CREATE DATABASE与create database相同 四个关键的实体分别是学院、老师、学生和课程,其中,学生跟学院是从属关系,这个关系从…...
【Android】动画原理解析
一,基础动画 基础动画,有四种,分别是平移(Translate)、缩放(Scale)、Rorate(旋转)、Alpha(透明度),对应Android中以下四种。 1,Animation基类 1,基本概念 1,插值器 插值器的作用,是控制动画过程的参数,可以理解为 时间(t)与动画进程(d)的函数,动画仅…...
C++从入门到实战(十四)初识STL与STL简介
C从入门到实战(十四)初识STL与STL简介 前言一、什么是 STL?二、STL 的版本三、STL六大组件(目前了解即可,后面会逐步讲解)1. 容器(Containers)—— 装数据的“盒子”2. 算法…...
力扣-142.环形链表II
题目描述 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 不允许修改 链表。 class Solution { public:ListNode *detectCycle(ListNode *head) {ListNode *fast head;ListNode *slow head;while (fast) {…...
ERC-20与ERC-721:区块链代币标准的双星解析
一、代币标准的诞生背景 在以太坊生态中,代币标准是构建去中心化应用(DApps)的基石。ERC-20与ERC-721分别代表同质化与非同质化代币的两大核心标准,前者支撑着90%以上的加密资产流通,后者则开启了数字资产唯一性的新时…...
图像管理与人脸识别工具深度解析
这篇Python应用程序代码实现了一个功能丰富的图像管理和人脸识别工具,它集成了多种实用功能,包括人脸检测与裁剪、屏幕截图以及生成PDF等核心功能。我将深入分析这个应用程序的架构、功能和实现方式,帮助读者理解其设计思路和关键技术点。 C…...
【图片合并PDF】一次性将多个文件夹里的图片批量按文件夹为单位合并PDF,多个文件夹图片合并PDF,基于WPF的实现方案
设计行业:设计师需要将项目设计稿按文件夹整理并合并为PDF交付客户 摄影行业:摄影师按主题分类的照片需要合并为PDF存档或分享 企业文档管理:市场调研部门需要将分散在不同文件夹的调研图片合并为PDF报告 教育领域:教师需要将学生的作业图片按班…...
Matlab 数控车床进给系统的建模与仿真
1、内容简介 Matlab217-数控车床进给系统的建模与仿真 可以交流、咨询、答疑 2、内容说明 略 摘 要:为提高数控车床的加工精度,对数控 车床进给系统中影响加工精度的主要因素进行了仿真分析研 动系统的数学模型,利用MATLAB软件中的动态仿真工具 究:依据机械动力学原理建立了…...
HOW - 在 Mac 上的 Chrome 浏览器中调试 Windows 场景下的前端页面
文章目录 为什么需要模拟 Windows 环境?一、修改 User-Agent 模拟 Windows 浏览器方法 1:通过 Chrome 开发者工具修改 UA方法 2:使用浏览器插件 二、模拟 Windows 的字体和滚动条样式1. 模拟 Windows 字体2. 强制显示滚动条(模拟 …...
微信小程序执行C语言库的详细方案
以下是微信小程序中执行C语言库的详细技术方案,分为环境准备、开发流程、优化技巧三个部分: 一、环境准备阶段 1. 工具链安装 # 安装Emscripten核心工具链 git clone https://github.com/emscripten-core/emsdk.git cd emsdk ./emsdk install latest .…...
如何用分布式防御抵扣大规模DDoS攻击?
DDoS攻击是当前最严峻的网络安全威胁之一,其通过海量请求耗尽目标资源,导致服务瘫痪。面对攻击规模的指数级增长,传统的单点防御已难以应对。本文将结合最新技术趋势,探讨分布式防御体系在抵御大规模DDoS攻击中的核心策略与实践。…...
【MySQL】存储引擎 - MyISAM详解
📢博客主页:https://blog.csdn.net/2301_779549673 📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! &…...
如何在Jmeter中调用C程序?
在JMeter中调用C语言程序可以通过以下几种方式实现: 方法一:使用OS Process Sampler JMeter的“OS Process Sampler”可以用来调用外部程序,包括C语言编写的可执行文件。 步骤: 准备C语言程序: 编写C语言代码并编译…...
PyTorch 版本、torchvision 版本和 Python 版本的对应关系
PyTorch 版本、torchvision 版本和 Python 版本的对应关系 在深度学习领域,PyTorch 及其配套库 torchvision 的使用极为广泛。但不同版本的 PyTorch、torchvision 与 Python 之间存在严格的对应关系,若版本搭配不当,会导致代码运行出错…...
构建高可维护、易测试的异步任务系统:基于 Celery + Redis + Eventlet 的模块化架构实践
引言:为什么我们需要一个结构清晰的异步任务系统? 在现代软件开发中,异步任务已经成为提升响应性能、解耦业务逻辑、支持高并发的重要手段。尤其对于测试工程师而言,异步任务往往意味着: 任务执行不可控状态追踪困难…...
《智能网联汽车 自动驾驶功能场地试验方法及要求》 GB/T 41798-2022——解读
目录 1. 适用范围与核心目标 2. 试验核心要求 2.1 试验场地与环境 2.2 试验设备与数据采集 2.3 试验车辆要求 3. 试验过程与通过条件 4. 关键试验场景与方法 4.1 交通信号识别及响应 4.2 基础设施与障碍物识别 4.3 行人及非机动车场景 4.4 紧急避险与风险策略 5. 特…...
删除链表倒数第N个节点
Leetcode(19): 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 分析: 首要目标就是找到第N个节点的前一个节点,因为只有通过这个节点(cur)才可进行对…...
创建型模式:抽象工厂(Abstract Factory)模式
一、概念与核心思想 抽象工厂(Abstract Factory)模式是创建型设计模式的重要成员,它提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。该模式将对象的创建逻辑封装在抽象工厂及其具体实现类中,客户端通过抽象工厂接口获取所需的对象族,实现对象创…...
预训练模型实战手册:用BERT/GPT-2微调实现10倍效率提升,Hugging Face生态下的迁移学习全链路实践
更多AI大模型应用开发学习内容,尽在聚客AI学院。 一. 预训练模型(PTM)核心概念 1.1 什么是预训练模型? 预训练模型(Pre-trained Model, PTM)是在大规模通用数据上预先训练的模型,通过自监督学…...
基于Flink的用户画像 OLAP 实时数仓统计分析
1.基于Flink的用户画像 OLAP 实时数仓统计分析 数据源是来自业务系统的T日数据,利用kakfa进行同步 拼接多个事实表形成大宽表,优化多流Join方式,抽取主键和外键形成主外键前置层,抽取外键和其余内容形成融合层,将4次事…...
php java go python面向对象的设计原则和常用设计模式
一、面向对象设计原则(OOP Design Principles) 是写出高内聚、低耦合、可维护系统的基础,重点是 SOLID 五大原则 其他补充原则。 📌 SOLID 五大设计原则: 原则名称全称核心思想示例关键词S 单一职责原则Single Respo…...
第十三节:图像形态学操作-腐蚀与膨胀
引言 图像形态学是数字图像处理领域中的一个重要分支,它主要研究图像中物体的形状和结构。作为形态学操作的基础,腐蚀(Erosion)和膨胀(Dilation)是两种最核心的操作,广泛应用于图像预处理、特征提取、目标检测等多个领域。OpenCV作为最流行的…...
数据结构 - 9( 位图 布隆过滤器 并查集 LRUCache 6000 字详解 )
一:位图 位图是一种高效的数据结构,它通过比特来表示某个值的存在与否,通常以连续的二进制位数组存储。每个比特位对应一个特定的状态,这种表示方式在内存效率和操作速度上具有显著优势,尤其适用于海量数据、整数以及…...