数据结构—(链表,栈,队列,树)
本文章写的比较乱,属于是缝合怪,很多细节没处理,显得粗糙,日后完善,今天赶时间了。
1. 红黑树的修复篇章
2. 红黑树的代码理解(部分写道注释之中了)
3. 队列与栈的代码
4. 重要是理解物理逻辑,从而理解代码逻辑
目录
一 链表
1. 单向链表
2. 双向链表
双向链表的操作(c语言)
1. linked_list_common.h
2. link.c
3. main.c
3. 循环列表
1. 单向循环列表
2. 双向循环列表
4. 静态链表
二 栈(stack)(代码暂不演示)
三 队列(queue) (代码暂不演示)
四 树(tree)
1. 二叉树(Binary Tree)
2. 二叉搜索树(BST)
3. AVL 树
4. B 树
5. 红黑树
1. red_black_common.h
2. red_black_tree.c
3. main.c
4. 总结
1. 左右旋
2. 修复(变色,左右旋转)
一 链表
链表(Linked List) 是一种线性数据结构,由一系列节点(Node)通过指针链接而成。与数组不同,链表的元素在内存中非连续存储,每个节点独立分配内存
类型 方向性 内存开销 适用场景 单向链表 单向 低 简单数据管理(如栈、队列) 双向链表 双向 高(2指针) 频繁双向遍历(如浏览器历史记录) 循环链表 环状 同单向/双向 轮询任务、循环缓冲区 静态链表 单向/双向 固定数组 无动态内存环境(如嵌入式开发)
单向链表:
实现栈(LIFO)、队列(FIFO)。
轻量级数据集合管理(如学生成绩表)。
双向链表:
浏览器前进/后退功能。
文本编辑器的撤销/重做操作。
循环链表:
操作系统进程调度(时间片轮转)。
音乐播放器的循环播放列表。
静态链表:
内存受限的嵌入式系统。
预分配固定内存池的实时系统。
(此处重点且详细的说双向列表,双向列表会了之后,其余两个也就差不多了)
1. 单向链表
结构定义
每个节点包含 数据域 和 指向下一个节点的指针。
C语言结构体:
typedef struct SNode {int data; // 数据域struct SNode *next; // 指向下一节点的指针 } SNode;
特点:
单向遍历,只能从头节点开始访问后续节点。
插入/删除操作需定位前驱节点。
示例操作:
// 在头节点后插入新节点 void insertAtHead(SNode **head, int val) {SNode *newNode = (SNode*)malloc(sizeof(SNode));newNode->data = val;newNode->next = *head;*head = newNode; }
2. 双向链表
结构定义
每个节点包含 数据域、指向前驱节点的指针 和 指向后继节点的指针。
C语言结构体:
typedef struct linked_list_node {// 节点数据void *data; // 8位// pre节点指针,指向的是前一个节点 8位struct linked_list_node *prev;// next指针指向的是下一个节点 8位struct linked_list_node *next;} node;// 2.定义链表-结构体,此结构点表示的是 typedef struct {// 头结点node *head;// 尾节点node *tail;// 节点的个数int size;} linked_list;
特点:
支持双向遍历(从头到尾或从尾到头)。
插入/删除操作更高效(可直接访问前驱和后继)。
双向链表的操作(c语言)
包含了前插插入,后插插入,中间插入,删除,查找等等
1. linked_list_common.h
#ifndef LINKED_LIST_COMMON
#define LINKED_LIST_COMMON/*双向链表结构节点表示首节点 前去节点 数据 后区节点*/// 节点声明,数据在次结构体,总体长度为24
typedef struct linked_list_node
{// 节点数据void *data; // 8位// pre节点指针,指向的是前一个节点 8位struct linked_list_node *prev;// next指针指向的是下一个节点 8位struct linked_list_node *next;} node;// 2.定义链表-结构体,此结构点表示的是
typedef struct
{// 头结点node *head;// 尾节点node *tail;// 节点的个数int size;} linked_list;// 3.创建一个节点需要自己开辟空间,即使用上的nide指针的
node *create_node(void *data);// 4.初始化链表
void init_linked_list(linked_list *list);// 中间插入
void insert_after(linked_list *list, node *prev, void *data);// 人为规定当前案例 都放入int类型数据
// 整数int类型比较函数
int compare_int(void *a, void *b);// 添加 prepend 和 append 的声明
void prepend(linked_list *list, void *data);
void append(linked_list *list, void *data);// 在链表中查找特定数据的节点,插入必须先查找对应的节点
node *search_node(linked_list *list, void *data, int (*compare)(void *, void *));// 示例:打印int数据链表的内容
void print_int_linked_list(linked_list *list);// 删除节点,进行三次判断,判断是否为头节点,判断是否为节点,否则就是中间节点,然后写出每个删除的逻辑
// 逻辑结束后,释放所被删除的内存空间
void delete_node(linked_list *linked, node *node);// last.清空链表
void clean_linked_list(linked_list *list);#endif
2. link.c
#include <stdio.h>
#include <stdlib.h>
#include "../inc/linked_list_common1.h"/*在此处定义
*/
// 1.创建一个节点需要自己开辟空间,即使用上的nide指针的
node *create_node(void *data)
{// 创建空间,准备存取数据,别忘记了释放空间// calloc(1, sizeof(node))由于calloc创建的是一个没有类型的类型的数据,需要给强转成相对应的类型嗯node *new_node = (node *)calloc(1, sizeof(node));// 如果内存无法开辟,即没有足够大的空间,会导致开辟失败if (new_node == NULL){printf("内存溢出,创建节点失败\n");exit(EXIT_FAILURE); // 异常退出}// 如果空间可以开辟,则使用结构体指针将其赋初始值new_node->data = data;new_node->prev = NULL;new_node->next = NULL;return new_node;
}// 2.初始化链表,因为暂时没有数据
void init_linked_list(linked_list *list)
{// 头结点list->head = NULL;// 尾节点list->tail = NULL;// 链表的节点个数list->size = 0;
}
// 7.在链表的中间插入节点。三个参数,即为,列表,前驱节点为参数,和数据
void insert_after(linked_list *list, node *prev, void *data)
{// 上一个节点的pre指向上上个数据,next指向下一个数据,要在中间插入一个数据的话,既要改变上一个节点的next,也要改变下一个节点的prev// 即在于找到一个prev即可找到上一个节点的next// 7.1判断要插入的prev的节点是否为null,没有的话,找不到前一个数据,无法插入if (prev == NULL){printf("前驱节点不能为NULL...\n");return; // 结束程序}// 7.2创建新节点 ,此节点就是要被插入的节点,node *new_node = create_node(data);// 7.3 修改新节点的prev和next指针,修改新节点的直接前驱指针,新节点的直接后继指针为 直接前驱的nextnew_node->prev = prev;new_node->next = prev->next;// 7.4 prev为尾节点,更新新节点为新的尾节点if (prev->next == NULL){list->tail = new_node;}else{// prev不是尾节点,更新prev旧的后继节点的prev指针指向新节点prev->next->prev = new_node;}// 设置prev的next指针指向新节点prev->next = new_node;// 链表节点个数+1list->size++;
}// 在链表头部插入数据
void prepend(linked_list *list, void *data)
{node *new_node = create_node(data);if (list->head == NULL){// 如果链表为空,头尾节点都指向新节点list->head = new_node;list->tail = new_node;}else{// 链表非空,更新头节点new_node->next = list->head;list->head->prev = new_node;list->head = new_node;}list->size++;
}// 在链表尾部插入数据
void append(linked_list *list, void *data)
{node *new_node = create_node(data);if (list->tail == NULL){// 如果链表为空,头尾节点都指向新节点list->head = new_node;list->tail = new_node;}else{// 链表非空,更新尾节点new_node->prev = list->tail;list->tail->next = new_node;list->tail = new_node;}list->size++;
}// 人为规定当前案例 都放入int类型数据
// 整数int类型比较函数
int compare_int(void *a, void *b)
{// 比较数值相减是否为0,0则表示相同return *(int *)a - *(int *)b;
}// 在链表中查找特定数据的节点,插入必须先查找对应的节点,容纳后才能执行中间插入操作,
// 即必须要知道前一个节点的位置,即他的prev
node *search_node(linked_list *list, void *data, int (*compare)(void *, void *))
{// 首先必须要从list的head开始遍历,此处名称为迭代,先获取list的head的节点node *current = list->head;// 遍历列表,查找节点while (current != NULL){// 比较函数返回0,表示两个值相等if (compare(current->data, data) == 0){// 返回找到的节点return current;}// 继续比较下一个节点current = current->next;}// 如果循环结束都没有找到数据对应的节点,说明该链表不存在该数据return NULL;
}// 示例:打印int数据链表的内容,全部内容,其作用与查找节点一样
void print_int_linked_list(linked_list *list)
{// 获取头结点node *current = list->head;printf("双向链表内容:\n");// 迭代器遍历while (current != NULL){printf("%d ", *(int *)current->data);// 继续下一个current = current->next;}printf("\n");printf("此时链表总共有%d个节点\n", list->size);
}// 删除节点,此处有带商榷
void delete_node(linked_list *list, node *node)
{// 判断节点不能为空if (node == NULL){printf("节点不能为空\n");return;}// 判断是否为头节点if (node == list->head){ // 如果是头节点,则使其下一个节点的list->head = node->next;if (list->head != NULL){list->head->prev = NULL;}else{// 如果删除后链表为空,更新尾节点list->tail = NULL;printf("本次删除的为头节点%d\n", *(int *)node->data);}}// 判断是否为尾节点else if (node == list->tail){list->tail = node->prev;if (list->tail != NULL){list->tail->next = NULL;}else{// 如果删除后链表为空,更新头节点list->head = NULL;printf("本次删除的为尾节点%d\n", *(int *)node->data);}}// 中间节点else{node->prev->next = node->next;node->next->prev = node->prev;printf("本次删除的为中部节点%d\n", *(int *)node->data);}// 释放节点内存free(node);list->size--;
}// last.清空链表
void clean_linked_list(linked_list *list)
{// 获取头结点,先用上一个节点找到下一个节点,然后删除上一个节点node *current = list->head;// 迭代器 获取节点,释放节点空间 利用迭代循环找到节点释放空间while (current != NULL){// 头结点不为Nullnode *temp = current;// 获取下一个节点current = current->next;// 释放节点的内存空间free(temp);}// 头结点list->head = NULL;// 尾节点list->tail = NULL;// 链表的节点个数list->size = 0;
}
3. main.c
#include <stdio.h>
#include <stdlib.h>
#include "../inc/linked_list_common1.h"int main(int argc, char const *argv[])
{// 1.初始化链表linked_list list; // 声明开辟内存init_linked_list(&list);// 2.在链表头部插入数据int a = 10, b = 20, c = 30;prepend(&list, &a);prepend(&list, &b);prepend(&list, &c);// 打印print_int_linked_list(&list);// 3.在链表尾部插入数据int e = 40, f = 50;append(&list, &e);append(&list, &f);// 打印print_int_linked_list(&list);// 4.在链表中间插入数据// 4.1查找某个节点int g = 60;node *prev = search_node(&list, &c, compare_int);insert_after(&list, prev, &g);// 打印print_int_linked_list(&list);// 删除节点// 查找要删除的节点,node *target_node = search_node(&list, &a, compare_int);if (target_node != NULL){delete_node(&list, target_node);}else{printf("未找到要删除的节点\n");}print_int_linked_list(&list);// last.清空链表clean_linked_list(&list);return 0;
}
3. 循环列表
特点:
无明确的头尾界限,适合循环访问场景(如轮询调度)。
1. 单向循环列表
结构定义
单向循环链表:尾节点的
next
指针指向头节点。
2. 双向循环列表
结构定义
双向循环链表:头节点的
prev
指向尾节点,尾节点的next
指向头节点。
4. 静态链表
结构定义
使用数组模拟链表,节点通过数组下标链接。
特点:
无需动态内存分配,适用于不支持指针的环境(如嵌入式系统)。
内存固定,无法动态扩展。
二 栈(stack)(代码暂不演示)
定义:后进先出(LIFO)的线性结构,仅允许在栈顶操作。
核心操作:
push
:入栈。
pop
:出栈。
peek
:查看栈顶元素。队列,和栈比较相似,特殊的线性表(执行先进先出,谁头谁尾,有待商榷)
循环队列:
链式队列:数据与 指针域
需要根据结构图来重新模拟一下结构体的创建的理念
首先明白一点,我大概都懂他们的逻辑结构关系,我也知道他们的指针其什么作用
1.明白队列的物理结构关系
2.根据物理结构关系来定义结构体(结构体为何有两个,两个分别是什么作用,为和不创建一个)
3.根据物理结构来定义这个数据结构,使用函数写出,让这个链表成为队列,即数据结构在c语言中并不是一种真正的结构,而是人为定义的,因为人类需要使用这种结构,例如现实问题,排队进游乐场等等
三 队列(queue) (代码暂不演示)
定义:先进先出(FIFO)的线性结构,队尾插入,队头删除。
核心操作:
enqueue
:入队。
dequeue
:出队。
front
:查看队头元素。重难点:
栈空判断:出栈前必须检查
top
是否为NULL
(否则导致未定义行为)。内存安全:出栈后必须释放节点内存。
应用场景:
函数调用栈(递归实现)。
括号匹配、表达式求值。
结构体:
// 1.定义队列中节点的 typedef struct queue_node {// 数据域void *data;// 指针域struct queue_node *next; } node;// 2.定义队列的结构体 typedef struct {// 对首节点node *front;// 对尾节点node *rear;// 队列中节点的个数int size; } queue;
四 树(tree)
树(Tree)是一种非线性数据结构,由节点(Node)和边(Edge)组成,满足以下条件:
每个树有且仅有一个根节点(Root)。
除根节点外,每个节点有且仅有一个父节点。
从根节点到任意节点有唯一路径。
1. 二叉树(Binary Tree)
定义:每个节点最多有 2 个子节点(左和右)。
特点:结构简单,适合递归操作。
应用:表达式树、哈夫曼编码。
C 代码结构:
typedef struct TreeNode {int data;struct TreeNode* left;struct TreeNode* right; } TreeNode;
2. 二叉搜索树(BST)
定义:左子树所有节点值 < 根节点值 < 右子树所有节点值。
特点:中序遍历结果为有序序列。
应用:动态数据排序、字典。
插入代码:
TreeNode* insertBST(TreeNode* root, int val) {if (root == NULL) {TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode));node->data = val;node->left = node->right = NULL;return node;}if (val < root->data) root->left = insertBST(root->left, val);else root->right = insertBST(root->right, val);return root; }
3. AVL 树
定义:平衡二叉搜索树,任意节点左右子树高度差 ≤ 1。
特点:通过旋转(左旋/右旋)保持平衡。
应用:数据库索引、实时高频查询。
结构扩展:
typedef struct AVLNode {int data;int height;struct AVLNode *left, *right; } AVLNode;
4. B 树
定义:多路平衡搜索树,每个节点可包含多个键和子节点。
特点:减少磁盘 I/O,适合大规模数据。
应用:文件系统、数据库存储。
5. 红黑树
定义:自平衡二叉搜索树,通过颜色标记和规则保持平衡。
特点:插入/删除效率高,广泛用于库函数(如 C++ STL)。
规则:
节点是红或黑。
根和叶子(NIL)是黑。
红节点的子节点必为黑。(即红不能连续)
任意节点到叶子的路径包含相同数量黑节点。
1.节点颜色:每个节点都是红色或黑色。
2.根节点:根节点必须是黑色。
3.叶子节点:所有的叶子节点(即空节点)都是黑色。
4.红色节点的约束:红色节点的子节点必须是黑色(即红色节点不能有红色子节点)。
5.黑色节点的平衡:从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
这些特性确保了红黑树的平衡性,使得其在最坏情况下的时间复杂度仍然保持在 O(logN)。具体来说,红黑树通过以下方式实现自平衡:
1. red_black_common.h
#ifndef RED_BLACK_COMMON_H
#define RED_BLACK_COMMON_H// 使用枚举 定义节点颜色
typedef enum
{RED,BLACK
} node_color;// 定义树,包含根节点,哨兵节,因为根节点与哨兵节点没有继续分支所以,树的结构体只包含两个数据
// 由于普通的节点,还有数据存在,即为令起一个结构体存放
typedef struct red_black_tree_common
{// 根节点tree_node *root_node;// 哨兵节点tree_node *nil_node;} tree;// 定义树的节点,普通树节点分为数据,左右子结点,及其这个节点的父节点(父节点有可能是根节点),节点颜色,
typedef struct tree_node
{// 1.数据域void *data;// 2.节点的颜色node_color color;// 3.父节点struct rb_tree_node *parent;// 4.左子节点struct rb_tree_node *left_child;// 5.右子节点struct rb_tree_node *right_child;
} tree_node;// 4.创建一个新的红黑树节点,新节点默认为红色,左右子节点和父节点都指向哨兵节点
// 定义树,返回值为树节点的指针类型,参数为tree指针,与数据指针
tree_node *create_node(tree *tree, void *data);// 5.初始化一棵空树,根节点为nil,并且哨兵节点颜色为黑色(最下面的叶子节点)
// 创建一个空树,空树只包含根节点与哨兵节点
tree *create_rb_tree();
/*左旋右旋,这层代码还是简单的,我想执导的是左右转的目的是什么,或者说在现实世界的应用情况在什么情况下可以用到左右旋?----在修复的时候用得到,要维护红黑树的平衡及规则左右旋转,先维护x与y的关系,即谁是谁的分支,重新定义x与y的双向关系1.先判断子结点上升的的节点与源节点的子关系,上升节点的分支与源节点的子关系2.判断父关系
(分支节点的的父节点)上升节点的某个分支不为哨兵节点的话,则判断其分支节点的指向为源节点(认爹)y->left_child->parent=x;x与y的关系有三种可能性1.x(源节点)为根节点,判断(x->parent==tree->nil_node),则y就等于根节点,即tree->root_node=y;2.即x不是根节点,判断x是其父节点的那个位置的节点,然后执行x->parent->left_child=y;3.另一个节点一样
*/// last1.释放节点
// 释放树节点的空间
void free_tree(tree *tree, tree_node *node);// last2.释放树
// 释放树的空间
void destroy_tree(tree *tree);#endif
2. red_black_tree.c
#include <stdio.h>
#include <stdlib.h>
#include "../inc/rb_tree_common.h"// 4.创建一个新的红黑树节点,新节点默认为红色,左右子节点和父节点都指向哨兵节点
rb_tree_node *create_node(rb_tree *tree, void *data)
{// 动态分配内存给新节点rb_tree_node *node = (rb_tree_node *)calloc(1, sizeof(rb_tree_node));if (node == NULL){printf("内存溢出,动态分配失败\n");exit(EXIT_FAILURE);}// 设置新节点存储的数据node->data = data;// 新节点的颜色默认为红色node->color = RED;// 左右子节点和父节点都指向哨兵节点node->parent = tree->nil_node;node->left_child = tree->nil_node;node->right_child = tree->nil_node;// 返回创建的节点return node;
}// 5.初始化一棵空树,根节点为nil,并且哨兵节点颜色为黑色(最下面的叶子节点)
rb_tree *create_rb_tree()
{// 动态分配内存给红黑树rb_tree *tree = (rb_tree *)calloc(1, sizeof(rb_tree));if (tree == NULL){printf("内存溢出,动态分配失败\n");exit(EXIT_FAILURE);}// 创建哨兵节点tree->nil_node = (rb_tree_node *)calloc(1, sizeof(rb_tree_node));if (tree->nil_node == NULL){printf("内存溢出,动态分配失败\n");exit(EXIT_FAILURE);}// 哨兵节点默认为黑色tree->nil_node->color = BLACK;// 初始化红黑树,没有插入任何节点// 根节点指向哨兵节点tree->root_node = tree->nil_node;return tree;
}/*
红黑树的插入过程和二叉查找时的插入过程基本类似,不同的地方在于红黑树插入新节点后,需要进行调整,以满足红黑树的性质:1.节点颜色:每个节点都是红色或黑色。2.根节点:根节点必须是黑色。3.叶子节点:所有的叶子节点(即空节点)都是黑色。4.红色节点的约束:红色节点的子节点必须是黑色(即红色节点不能有红色子节点)。5.黑色节点的平衡:从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点。
这些特性确保了红黑树的平衡性,使得其在最坏情况下的时间复杂度仍然保持在 O(logN)。具体来说,红黑树通过以下方式实现自平衡:旋转操作:包括左旋和右旋,用于调整节点的位置以维持树的平衡。变色操作:用于调整节点的颜色以满足红黑树的特性。
*/
// 6.左旋操作:左旋x,将x节点的右子节点提升为其父节点,并将x下移至其右子节点的左子节点的,左旋用于红黑树失衡调整的结构
void left_rotate(rb_tree *tree, rb_tree_node *x)
{// 6.1设置y为x的右子节点rb_tree_node *y = x->right_child;// 6.2将y的左子树作为x的右子树x->right_child = y->left_child;// 6.3 如果y的左子节点不是哨兵节点,要更改其父节点为xif (y->left_child != tree->nil_node){y->left_child->parent = x;}// 6.4让y的父节点指向x的父节点y->parent = x->parent;// 6.5如果x是根节点,更新y为根节点if (x->parent == tree->nil_node){// 如果x是根节点,则更新根节点为ytree->root_node = y;}else if (x == x->parent->left_child){// x是父节点的左子节点,更新y为其左子节点x->parent->left_child = y;}else{x->parent->right_child = y;}// 6.6设置x为y的左子节点y->left_child = x;// 6.7设置x的父节点为yx->parent = y;
}// 7.右旋操作:右旋y,将y节点的左子节点提升为其父节点,并y下移至其左子节点的右子节点的,右旋用于红黑树失衡调整的结构
void right_rotate(rb_tree *tree, rb_tree_node *y)
{// 7.1设置x为y的左子节点rb_tree_node *x = y->left_child;// 7.2设置x的右子节点为y的左子节点y->left_child = x->right_child;if (x->right_child != tree->nil_node){// 如果x的右子节点不为哨兵节点 ,更新其父节点为yx->right_child->parent = y;}// 7.3让x的父节点指向y的父节点x->parent = y->parent;if (y->parent == tree->nil_node){// 更新x为根节点tree->root_node = x;}else if (y == y->parent->right_child){y->parent->right_child = x;}else{y->parent->left_child = x;}// 7.4设置y为x的右子节点x->right_child = y;// 7.5更新y的父节点为xy->parent = x;
}// last1.释放节点
void free_tree(rb_tree *tree, rb_tree_node *node)
{if (node != tree->nil_node){// 释放左子节点free_tree(tree, node->left_child);// 释放右子节点free_tree(tree, node->right_child);// 释放节点本身free(node);}
}// last2.释放树
void destroy_tree(rb_tree *tree)
{// 从root节点,根节点开始释放free_tree(tree, tree->root_node);// 释放哨兵节点free(tree->nil_node);// 释放红黑树的内存空间free(tree);
}
3. main.c
#include <stdio.h>
#include "../inc/rb_tree_common.h"int main(int argc, char const *argv[])
{//1.创建红黑树rb_tree *tree=create_rb_tree();//last.2 释放红黑树destroy_tree(tree);return 0;
}
4. 总结
1. 左右旋
左旋右旋,这层代码还是简单的,我想执导的是左右转的目的是什么,或者说在现实世界的应用情况
在什么情况下可以用到左右旋?----在修复的时候用得到,要维护红黑树的平衡及规则左右旋转,先维护x与y的关系,即谁是谁的分支,重新定义x与y的双向关系
1.先判断子结点
上升的的节点与源节点的子关系,上升节点的分支与源节点的子关系
2.判断父关系
(分支节点的的父节点)上升节点的某个分支不为哨兵节点的话,则判断其分支节点的指向为源节点(认爹)y->left_child->parent=x;
x与y的关系有三种可能性
1.x(源节点)为根节点,判断(x->parent==tree->nil_node),则y就等于根节点,即tree->root_node=y;
2.即x不是根节点,判断x是其父节点的那个位置的节点,然后执行x->parent->left_child=y;
3.另一个节点一样
2. 修复(变色,左右旋转)
这个我不知道怎么去描述。等有图了继续说
通过颜色翻转,将红色冲突向上传递,保证局部黑高不变,但可能引发更高层的红红冲突,需继续循环处理。
相关文章:
数据结构—(链表,栈,队列,树)
本文章写的比较乱,属于是缝合怪,很多细节没处理,显得粗糙,日后完善,今天赶时间了。 1. 红黑树的修复篇章 2. 红黑树的代码理解(部分写道注释之中了) 3. 队列与栈的代码 4. 重要是理解物理逻辑&a…...
GitHub 趋势日报 (2025年05月12日)
本日报由 TrendForge 系统生成 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日整体趋势 Top 10 排名项目名称项目描述今日获星总星数语言1harry0703/MoneyPrinterTurbo利用ai大模型,一键生成高清短视频使用…...
ebook2audiobook开源程序使用动态 AI 模型和语音克隆将电子书转换为带有章节和元数据的有声读物。支持 1,107+ 种语言
一、软件介绍 文末提供程序和源码下载 ebook2audiobook开源程序使用动态 AI 模型和语音克隆将电子书转换为带有章节和元数据的有声读物。支持 1,107 种语言。从电子书到带有章节和元数据的有声读物的 CPU/GPU 转换器,使用 XTTSv2、Bark、Vits、Fairseq、YourTTS …...
《算法导论(第4版)》阅读笔记:p39-p48
《算法导论(第4版)》学习第 13 天,p39-p48 总结,总计 10 页。 一、技术总结 1. recurrence/recurrence equation 书里面 recurrence(递归式) 和 recurrence equation(递归方程) 指的是同一个东西。 二、英语总结(生词:2) 1. squint (1)…...
c语言第一个小游戏:贪吃蛇小游戏07
贪吃蛇吃饭喽 所谓贪吃蛇的食物,也就是创建一个和蛇身一样的结构体,只是这个结构体不是链表,也是将这个结构体设置hang和lie坐标,放进gamepic进行扫描,扫到了就也是做操作将 ## 打出来 #include <curses.h> #i…...
(七)深度学习---神经网络原理与实现
分类问题回归问题聚类问题各种复杂问题决策树√线性回归√K-means√神经网络√逻辑回归√岭回归密度聚类深度学习√集成学习√Lasso回归谱聚类条件随机场贝叶斯层次聚类隐马尔可夫模型支持向量机高斯混合聚类LDA主题模型 一.神经网络原理概述 二.神经网络的训练方法 三.基于Ker…...
VSCode中Node.js 使用教程
一、visual studio code下载与安装 二、修改vscode主题颜色 三、汉化 菜单view-->Command Palette...,输入Configure Display Language。 重启之后如下: 四、安装node.js Node.js 是一个基于Chrome V8引擎的JavaScript运行环境,使用了事件驱动、非阻…...
web 自动化之 KDT 关键字驱动详解
一、什么是关键字驱动? 1、什么是关键字驱动?(以关键字函数驱动测试) 关键字驱动又叫动作字驱动,把项目业务封装成关键字函数,再基于关键字函数实现自动化测试 2、关键字驱动测试原理 关键字驱动测试是一…...
web 自动化之 yaml 数据/日志/截图
文章目录 一、yaml 数据获取二、日志获取三、截图 一、yaml 数据获取 需要安装 PyYAML 库 import yaml import os from TestPOM.common import dir_config as Dirdef read_yaml(key,file_name"test_datas.yaml"):file_path os.path.join(Dir.testcases_dir, file_…...
基于javaweb的SpringBoot酒店管理系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...
数学复习笔记 6
前言 复习一下行列式的一些基本的题。感觉网课有点没跟上了。今天花点时间跟上网课的进度。要紧跟进度,然后剩下的时间再去复习前面的内容。多复习,提升自己的解题能力。 行列式和矩阵 三年级,我现在是三年级下册。。。马上就要结束大学的…...
JS Map使用方法
JS Map使用方法 Map 是 ES6 引入的一种新的数据结构,它类似于对象(Object),但提供了更强大的键值对存储功能。 文章目录 JS Map使用方法基本特性基本用法创建 Map常用方法遍历方法 与 Object 的区别实际应用示例示例1:…...
大模型分布式光伏功率预测实现详解
一、引言 随着全球能源结构向可再生能源转型,光伏发电作为清洁能源的重要组成部分,其装机容量持续快速增长。然而,光伏发电具有显著的间歇性和波动性特点,给电力系统的稳定运行带来了巨大挑战。准确的光伏功率预测对于电网调度、电力市场交易和电站运营管理至关重要。近年…...
武汉大学无人机视角下的多目标指代理解新基准!RefDrone:无人机场景指代表达理解数据集
作者:Zhichao Sun, Yepeng Liu, Huachao Zhu, Yuliang Gu, Yuda Zou, Zelong Liu, Gui-Song Xia, Bo Du, Yongchao Xu 单位:武汉大学计算机学院 论文标题:RefDrone: A Challenging Benchmark for Drone Scene Referring Expression Compreh…...
【LLM模型】如何构建自己的MCP Server?
什么是 MCP? Model Context Protocol (MCP) 是一种协议,它允许大型语言模型(LLMs)访问自定义的工具和服务。Trae 中的智能体作为 MCP 客户端可以选择向 MCP Server 发起请求,以使用它们提供的工具。你可以自行添加 MC…...
SQL 索引优化指南:原理、知识点与实践案例
SQL 索引优化指南:原理、知识点与实践案例 索引的基本原理 索引是数据库中用于加速数据检索的数据结构,类似于书籍的目录。它通过创建额外的数据结构来存储部分数据,使得查询可以快速定位到所需数据而不必扫描整个表。 索引的工作原理 B-…...
java基础-方法的重写、super关键字
1.定义:子类可以根据需要改写从父类那继承来的方法,执行时,子类的方法会覆盖父类的方法 2.要求: (1)子类和父类的方法必须同名,同参数列表 (2)父类中private修饰的方法…...
技术并不能产生一个好的产品
技术是产生一个好的产品充分条件,不是必要条件。 当笔者到了40岁的年龄时间,发现再怎么努力提升技术,也没办法挽救烂的产品设计。 一个好的产品,首先要找准自己的定位,不能动不动就把自己拿一线品牌来比较。 好的产品…...
lubuntu 系统详解
Lubuntu 系统详解:轻量高效的 Ubuntu 衍生版 一、系统概述 定位与背景: Lubuntu 是 Ubuntu 的官方衍生版本(Flavor),专注于轻量性与高效性,旨在为低配置设备(如老旧电脑、上网本、低配笔记本 …...
《设备管理与维修》审核严吗?“修改后再投”是拒稿了吗?
有过论文投稿经验的朋友,可能在审核后收到过“修改后再投”的回复。有些期刊可能是真的建议投稿人在修改后再投稿,有些则可能是标准的拒稿模板。 《设备管理与维修》审核严吗?收到“修改后再投”的回复该怎么办?下面我就来分享下之…...
2025年5月-信息系统项目管理师高级-软考高项一般计算题
决策树和期望货币值 加权算法 自制和外购分析 沟通渠道 三点估算PERT 当其他条件一样时,npv越大越好...
界面组件DevExpress WPF中文教程:Grid - 如何自定义Band Header外观?
DevExpress WPF拥有120个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…...
Supabase 的入门详细介绍
Supabase 是什么? 简单来说,Supabase 是一个开源的 Firebase 替代品。它提供了一整套后端即服务 (BaaS - Backend as a Service) 的工具,让你能够快速构建应用程序的后端,而无需自己从头搭建和管理服务器、数据库等基础设施。 S…...
【实战】基于 ABP vNext 构建高可用 S7 协议采集平台(西门子 PLC 通信全流程)
🚀🔧【实战】基于 ABP vNext 构建高可用 S7 协议采集平台(西门子 PLC 通信全流程)📊 📑 目录 🚀🔧【实战】基于 ABP vNext 构建高可用 S7 协议采集平台(西门子 PLC 通信全…...
20、map和set、unordered_map、un_ordered_set的复现
一、map 1、了解 map的使用和常考面试题等等,看这篇文章 map的key是有序的 ,值不可重复 。插入使用 insert的效率更高,而在"更新map的键值对时,使用 [ ]运算符效率更高 。" 注意 map 的lower和upper那2个函数&#x…...
leetcode 189. 轮转数组
题目描述 代码: class Solution { public:void rotate(vector<int>& nums, int k) {int len nums.size();k k % len;reverse(nums,0,len-1);reverse(nums,0,k-1);reverse(nums,k,len-1);}void reverse(vector<int>& nums,int left,int right…...
得物0509面试手撕题目解答
题目 使用两个栈(一个无序栈和一个空栈)将无序栈中的元素转移到空栈,使其有序,不允许使用其他数据结构。 示例:输入:[3, 1, 6, 4, 2, 5],输出:[6, 5, 4, 3, 2, 1] 思路与代码 如…...
8天Python从入门到精通【itheima】-6~10
目录 7节-开发出第一个Python程序: 1.在cmd窗口写下第一个最简单的程序:Hello World!!! 9节: 1.如何卸载python: 2.报错:不是可运行的程序 编辑 3.报错:无法初始化设备PRN: 4.报错&…...
Qt —— 使用Enigma Virtual Box将Qt程序打包为独立可运行exe(附:完整打包方法且完美运行)
🔔 Qt 相关技术、疑难杂症文章合集(掌握后可自封大侠 ⓿_⓿)(记得收藏,持续更新中…) 打包结果 1、如下图,准备好Qt已打包后程序文件夹。附 Qt —— 在Windows下打包Qt应用程序(在其他Windows电脑下使用)...
大语言模型RLHF训练框架全景解析:OpenRLHF、verl、LLaMA-Factory与SWIFT深度对比
引言 随着大语言模型(LLM)参数规模突破千亿级,基于人类反馈的强化学习(RLHF)成为提升模型对齐能力的关键技术。OpenRLHF、verl、LLaMA-Factory和SWIFT作为开源社区的四大标杆框架,分别通过分布式架构、混合…...
VTK|类似CloudCompare的比例尺实现1-源码分析
文章目录 CloudCompare源码分析void ccGLWindowInterface::drawScale(const ccColor::Rgbub& color)🧩 总体功能🧠 函数逐步解析✅ 1. 断言只在正交模式下使用✅ 2. 计算显示的实际长度✅ 3. 字体和图形区域准备✅ 4. 计算比例尺图形的绘制位置✅ 5.…...
【计算机视觉】OpenCV实战项目:基于Tesseract与OpenCV的字符识别系统深度解析
基于Tesseract与OpenCV的字符识别系统深度解析 1. 项目概述2. 技术原理与算法设计2.1 图像预处理流水线1) 形态学操作2) 自适应阈值 2.2 Tesseract OCR引擎 3. 实战部署指南3.1 环境配置3.2 项目结构优化建议3.3 增强版代码实现 4. 常见问题与解决方案4.1 Tesseract路径错误4.2…...
CVE-2025-31258 macOS远程视图服务沙箱逃逸漏洞PoC已公开
苹果公司近日针对macOS系统中新披露的CVE-2025-31258漏洞发布补丁,该漏洞可能允许恶意应用程序突破沙箱限制,获取未授权的系统资源访问权限。在安全研究员Seo Hyun-gyu公开概念验证(PoC)利用代码后,该漏洞已在macOS Se…...
使用CAS操作实现乐观锁的完整指南
乐观锁是一种高效的并发控制机制,而CAS(Compare-And-Swap)是实现乐观锁的核心技术。下面我将详细介绍如何通过CAS操作实现乐观锁。 一、CAS操作原理 CAS(Compare-And-Swap)是一种原子操作,包含三个操作数: 内存位置(V)预期原值(A)新值(B) …...
java之网络编程
文章目录 网络编程概述什么是网络编程基本的通信架构CS架构BS架构 Java提供了哪些网络编程解决方案? 网络编程三要素IPIP地址IP域名(Domain Name)DNS域名解析(Domain Name System)公网IP、内网IP本机IPInetAddress类In…...
苍穹外卖--新增菜品
1.需求分析和设计 产品原型 业务规则: 菜品名称必须是唯一的 菜品必须属于某个分类下,不能单独存在 新增菜品时可以根据情况选择菜品的口味 每个菜品必须对应一张图片 接口设计: 根据类型查询分类(已完成) 文件上传 新增菜品 根据类型…...
Spark处理过程-转换算子
(一)RDD的处理过程 Spark使用Scala语言实现了RDD的API,程序开发者可以通过调用API对RDD进行操作处理。RDD的处理过程如图所示; RDD经过一系列的“转换”操作,每一次转换都会产生不同的RDD,以供给下一次“转换”操作使…...
运行Spark程序-在Spark-shell——RDD
一、基本概念 RDD(弹性分布式数据集)是 Apache Spark 的核心抽象,是 Spark 提供的最基本的数据处理单元。理解 RDD 的概念对于掌握 Spark 编程至关重要。以下是 RDD 的核心概念和特性: 1. 什么是 RDD? 定义…...
Qt应用程序启动时的一些思路:从单实例到性能优化的处理方案
程序启动时优化的价值 在桌面软件开发领域,应用程序的启动过程就像音乐的序曲,决定了用户对软件品质的第一印象。比如首次启动等待超过3秒时,会让大多数用户产生负面看法,而专业工具软件的容忍阈值甚至更低。Qt框架作为跨平台开发…...
vue3父子组件传值
父 → 子:props 父组件 <template><ChildComponent :message"parentMessage" :user"user" /> </template><script setup> import ChildComponent from ./ChildComponent.vue; const parentMessage Hello from paren…...
中国品牌日 | 以科技创新为引领,激光院“风采”品牌建设结硕果
品牌,作为企业不可或缺的隐形财富,在当今竞争激烈的市场环境中,其构建与强化已成为推动企业持续繁荣的关键基石。为了更好地保护自主研发产品,激光院激光公司于2020年3月7日正式注册“风采”商标,创建拥有自主知识产权…...
合合信息上线智能文档处理领域首批MCP服务,助力企业快速搭建Agent
随着大模型及Agent技术的飞速发展,通过大模型调用外部工具正在成为AI应用开发的新范式。然而,由于不同大模型的调用结构和参数格式各异,开发者需要分别编写工具调用逻辑,AI工具集成效率低下,MCP(Model Cont…...
佰力博科技与您探讨表面电阻的测试方法及应用领域
表面电阻测试是一种用于测量材料表面电阻值的技术,广泛应用于评估材料的导电性能、静电防护性能以及绝缘性能。 1、表面电阻的测试测试方法: 表面电阻测试通常采用平行电极法、同心圆电极法和四探针法等方法进行。其中,平行电极法通过在试样…...
【DeepSeek】判断两个 PCIe 设备是否属于**同一个 PCIe 子树
在 Linux 系统中,判断两个 PCIe 设备是否属于**同一个 PCIe 子树(Subtree)**是 P2P 通信的关键前提。以下是具体方法和步骤: 一、基本原理 两个 PCIe 设备属于同一子树的条件: 共享同一 Root Port:它们的…...
一份完整的高级前端性能优化手册
以下是一份完整的高级前端性能优化手册,涵盖核心原理、关键指标、优化策略及工具链,适合中大型项目深度优化: 高级前端性能优化手册 🚀 以用户体验为核心的极致性能实践 一、性能指标体系与度量 1. 核心性能指标 (Core Web Vitals) LCP (Largest Contentful Paint):最大…...
Leetcode 3543. Maximum Weighted K-Edge Path
Leetcode 3543. Maximum Weighted K-Edge Path 1. 解题思路2. 代码实现 题目链接:3543. Maximum Weighted K-Edge Path 1. 解题思路 这一题思路上就是一个遍历的思路,我们只需要考察每一个节点作为起点时,所有长为 k k k的线段的长度&…...
agentmain对业务的影响
前面一篇已经说了java agent技术主要有premain和agentmain两种形式,如果大部分业务已经在线上运行的话,不方便用premain的方式来实现,所以agentmain的方式是更加通用、灵活的 由于RASP是与用户业务运行在同一个jvm中的 ,所以RASP…...
【前端】【JavaScript】【总复习】四万字详解JavaScript知识体系
JavaScript 前端知识体系 📌 说明:本大纲从基础到高级、从语法到应用、从面试到实战,分层级讲解 JavaScript 的核心内容。 一、JavaScript 基础语法 1.1 基本概念 1.1.1 JavaScript 的发展史与用途 1. 发展简史 1995 年:JavaS…...
开源模型应用落地-qwen模型小试-Qwen3-8B-融合VLLM、MCP与Agent(七)
一、前言 随着Qwen3的开源与技术升级,其在企业中的落地场景正加速拓展至多个垂直领域。依托Agent智能体能力 和MCP协议的工具调用接口 ,Qwen3可深度融入企业业务流程,为企业提供从需求解析到自动化开发的全链路支持。 本篇将介绍如何实现Qwen3-8B模型集成MCP实现智能体交互。…...
【Linux学习笔记】理解一切皆文件实现原理和文件缓冲区
【Linux学习笔记】理解一切皆文件实现原理和文件缓冲区 🔥个人主页:大白的编程日记 🔥专栏:Linux学习笔记 前言 哈喽,各位小伙伴大家好!上期我们讲了重定向 今天我们讲的是理解一切皆文件实现原理和文件缓冲区。话不…...