【数据结构】(C语言):二叉搜索树(不使用递归)
二叉搜索树:
- 非线性的,树是层级结构。
- 基本单位是节点,每个节点最多2个子节点。
- 有序。每个节点,其左子节点都比它小,其右子节点都比它大。
- 每个子树都是一个二叉搜索树。每个节点及其所有子节点形成子树。
- 可以是空树。
C语言实现:(使用链表实现,不使用递归)
创建结构体数据类型(记录二叉搜索树的根节点和数据个数):
typedef struct Link
{LinkNode *root; // 根节点int length; // 统计有多少数据
} LinkBST; // 别名
创建二叉搜索树,并初始化:
LinkBST bst;
bst.root = NULL; // 根节点,初始化为NULL
bst.length = 0; // 数据个数,初始化为0
创建节点(结构体数据类型),并创建具体节点实例的函数:
// 节点(结构体数据类型)
typedef struct Node
{int value; // 数据类型为整型struct Node *left; // 左子节点struct Node *right; // 右子节点
} LinkNode; // 别名
// 函数:创建节点
LinkNode *createNode(int data)
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode)); // 分配节点内存空间if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data; // 数据node->left = NULL; // 左子节点,初始化为NULLnode->right = NULL; // 右子节点,初始化为NULLreturn node;
}
添加元素:
从根节点开始,比对数值。若比它小,往左子树比对;若比它大,往右子树比对;直到找到为空,则为新元素的位置。
void add(LinkBST *bst, int data) // add a element to the tree
{LinkNode *newNode = createNode(data);// 若是空树,根节点就是新节点if(bst->root == NULL){bst->root = newNode;bst->length++;return ;}// 非空树,比根节点数值小,往左边比对,比根节点数值大,往右边比对LinkNode *cur = bst->root;while(1){if(data == cur->value) return ;if(data < cur->value){if(cur->left == NULL){cur->left = newNode;bst->length++;return ;}cur = cur->left;}else if(data > cur->value){if(cur->right == NULL){cur->right = newNode;bst->length++;return ;}cur = cur->right;}}
}
删除元素:
- 若删除的节点为叶子节点(即无子节点),则直接删除。
- 若删除的节点只有左子节点,则左子节点替代删除节点。
- 若删除的节点只有右子节点,则右子节点替代删除节点。
- 若删除的节点既有左子节点又有右子节点,则找到直接前驱(即删除节点的左子树中的最大值,即删除节点的左子节点的最右节点),直接前驱的值替代删除节点的值,删除直接前驱节点。
void delete(LinkBST *bst,int data) // delete a element from the tree
{// 函数:删除节点的具体操作LinkNode *del(LinkNode *node){// 只有右子节点,右子节点替代删除节点if(node->left == NULL){bst->length--;return node->right;}// 只有左子节点,左子节点替代删除节点if(node->right == NULL){bst->length--;return node->left;}// 左右子节点都有,直接前驱(左子节点的最右节点,即左子树中最大值)替代删除节点,删除直接前驱if(node->left && node->right){LinkNode *tmp = node, *cur = node->left;while(cur->right){tmp = cur;cur = cur->right;}node->value = cur->value;bst->length--;if(tmp != node) tmp->right = cur->left;else tmp->left = cur->left;return node;}}// 函数:找到删除节点void delNode(int data){LinkNode *parent, *cur = bst->root;while(1){if(cur == NULL) return ;if(data == cur->value){// 删除节点若是根节点,根节点接收删除后的节点if(cur == bst->root) bst->root = del(cur);// 删除节点若是左子节点,父节点的左子节点接收删除后的节点else if(data < parent->value) parent->left = del(cur);// 删除节点若是右子节点,父节点的右子节点接收删除后的节点else if(data > parent->value) parent->right = del(cur);return ;}if(data < cur->value){parent = cur;cur = cur->left;}else if(data > cur->value){parent = cur;cur = cur->right;}}}// 空树,直接退出程序if(bst->root == NULL) return ;delNode(data);
}
遍历元素:
前序遍历:(顺序:根节点、左子节点、右子节点)
使用数组实现栈(后进先出),数量:一个栈。
1、起始栈中元素为根节点。2、栈中元素依次出栈(并打印),找到元素的右节点和左节点依次入栈(注意:先右后左)。3、重复2,直到栈为空。
void pretraverse(LinkBST *bst) // show element one by one,(root,left,right)
{LinkNode *cur = NULL;// 指针数组(数组元素是指针),实现栈(后进先出)LinkNode *arr[bst->length];int n = 1;arr[n-1] = bst->root;printf("pretravel: ");while(n != 0){cur = arr[n-1];printf("%d ", cur->value);n--;if(cur->right){arr[n] = cur->right;n++;}if(cur->left){arr[n] = cur->left;n++;}}printf("\n");
}
中序遍历:(顺序:左子节点、根节点、右子节点)
使用数组实现栈(后进先出),数量:一个栈。
1、从根节点开始遍历,根节点入栈。2、找左节点依次入栈,找到最左节点后,栈中元素依次出栈(并打印),找右节点入栈。3、重复2,直到节点不存在或者栈为空。
void midtraverse(LinkBST *bst) // show element one by one,(left,root,right)
{printf("midtravel: ");LinkNode *cur = bst->root;// 指针数组(数组元素是指针),实现栈(后进先出)LinkNode *arr[bst->length];int n = 0;while(cur || n != 0){if(cur){arr[n] = cur;n++;cur = cur->left;}else{cur = arr[n-1];printf("%d ", cur->value);n--;cur = cur->right;}}printf("\n");
}
后序遍历:(顺序:左子节点、右子节点、根节点)
使用数组实现栈(后进先出),数量:两个栈(辅助栈,目标栈)。
1、辅助栈中起始元素为根节点。2、辅助栈中元素依次出栈(并入栈目标栈),找到元素的左节点和右节点依次入栈辅助栈(注意:先左后右)。3、重复2,直到辅助栈为空。4、遍历目标栈,并打印。
void posttraverse(LinkBST *bst) // show element one by one,(left,right,root)
{LinkNode *cur = NULL;// 指针数组(数组元素是指针),实现栈(后进先出)LinkNode *arr[bst->length]; // 辅助栈LinkNode *brr[bst->length]; // 目标栈int n = 1, m = 0;arr[n-1] = bst->root;while(n != 0){ cur = brr[m] = arr[n-1]; // 辅助栈出栈,目标栈入栈n--;m++;if(cur->left){arr[n] = cur->left; // 辅助栈入栈n++;}if(cur->right){arr[n] = cur->right; // 辅助栈入栈n++;}}// 遍历目标栈printf("posttravel: ");for(int i = m - 1; i >= 0; i--){printf("%d ", brr[i]->value);}printf("\n");
}
广度遍历(层级遍历):
使用链表实现队列(先进先出),数量:一个队列。
1、队列中起始元素为根节点。2、队列中元素依次从队头出队(并打印),找到元素的左节点和右节点依次从队尾入队(注意:先左后右)。3、重复2,直到队列为空。
void breadthtraverse(LinkBST *bst) // show element one by one,(levels)
{printf("threadtravel: ");// 链表:实现队列(先进先出),注:链表的函数在bstqueue.c(完整代码中展示)Queue queue;queue.header = createQnode(bst->root); // 头指针,指向第一个元素queue.tail = NULL; // 尾指针,指向最后一个元素LinkNode *cur = NULL;while(queue.header){cur = queue.header->bstnode;printf("%d ", cur->value);popQnode(&queue); // 从队头出队(函数在bstqueue.c)if(cur->left){addQnode(&queue, cur->left); // 从队尾入队(函数在bstqueue.c)}if(cur->right){addQnode(&queue, cur->right); // 从队尾入队(函数在bstqueue.c)}}printf("\n");
}
查找元素:
从根节点开始,比对数值。若比它小,往左子树查找;若比它大,往右子树查找;直到找到该元素,则返回1(true),若没有,则返回0(false)。
int find(LinkNode *node, int data) // if find data,return 1(true),or return 0(false)
{LinkNode *cur = node;while(cur){if(data == cur->value) return 1;if(data < cur->value) cur = cur->left;else if(data > cur->value) cur = cur->right;}return 0;
}
完整代码:(bstree.c,bstqueue.c(链表实现的队列,用于广度遍历))
// bstree.c
#include <stdio.h>
#include <stdlib.h>
#include "bstqueue.c" // 引入链表实现的队列,用于广度遍历/* structure */
typedef struct Node // node of the binary search tree(bst)
{int value; // data type is integerstruct Node *left; // left child nodestruct Node *right; // right child node
} LinkNode;typedef struct Link //bst(Linkedlist)
{LinkNode *root; // root nodeint length; // the number of the tree
} LinkBST;/* function prototype */
void add(LinkBST *, int); // add a element
void delete(LinkBST *,int); // delete a element
void pretraverse(LinkBST *); // show element one by one,(root,left,right)
void midtraverse(LinkBST *); // show element one by one,(left,root,right)
void posttraverse(LinkBST *); // show element one by one,(left,right,root)
void breadthtraverse(LinkBST *); // show element one by one,(levels)
int find(LinkNode *, int); // if find data,return 1(true),or return 0(false)/* main function */
int main(void)
{// create binary search tree and initializationLinkBST bst;bst.root = NULL;bst.length = 0;printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);add(&bst, 15);add(&bst, 8);add(&bst, 23);add(&bst, 19);add(&bst, 10);add(&bst, 6);add(&bst, 9);add(&bst, 12);printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);pretraverse(&bst);midtraverse(&bst);posttraverse(&bst);breadthtraverse(&bst);printf("find 10(1:true, 0:false): %d\n", find(bst.root, 10));printf("find 11(1:true, 0:false): %d\n", find(bst.root, 11));delete(&bst, 23);delete(&bst, 15);delete(&bst, 6);printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);pretraverse(&bst);midtraverse(&bst);posttraverse(&bst);breadthtraverse(&bst);return 0;
}/* subfunction */
LinkNode *createNode(int data) // create a node of the binary search tree
{LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));if(node == NULL){perror("Memory allocation failed");exit(-1);}node->value = data;node->left = NULL;node->right = NULL;return node;
}void add(LinkBST *bst, int data) // add a element to the tree
{LinkNode *newNode = createNode(data);// if empty, root is newNodeif(bst->root == NULL){bst->root = newNode;bst->length++;return ;}// if not empty, smaller,to left, biger,to rightLinkNode *cur = bst->root;while(1){if(data == cur->value) return ;if(data < cur->value){if(cur->left == NULL){cur->left = newNode;bst->length++;return ;}cur = cur->left;}else if(data > cur->value){if(cur->right == NULL){cur->right = newNode;bst->length++;return ;}cur = cur->right;}}
}void delete(LinkBST *bst,int data) // delete a element from the tree
{// subfunction: delete the nodeLinkNode *del(LinkNode *node){// if only right child, return right child nodeif(node->left == NULL){bst->length--;return node->right;}// if only left child, return left child nodeif(node->right == NULL){bst->length--;return node->left;}// both left and right, the max on the left replace the delete node and delete itif(node->left && node->right){LinkNode *tmp = node, *cur = node->left;while(cur->right){tmp = cur;cur = cur->right;}node->value = cur->value;bst->length--;if(tmp != node) tmp->right = cur->left;else tmp->left = cur->left;return node;}}// subfunction: find the delete nodevoid delNode(int data){LinkNode *parent, *cur = bst->root;while(1){if(cur == NULL) return ;if(data == cur->value){// delete node is root,root receive the node after deleteif(cur == bst->root) bst->root = del(cur);// delete node is left,left child of parent receive the node after deleteelse if(data < parent->value) parent->left = del(cur);//delete node is right,right child of parent receive the node after deleteelse if(data > parent->value) parent->right = del(cur);return ;}if(data < cur->value){parent = cur;cur = cur->left;}else if(data > cur->value){parent = cur;cur = cur->right;}}}if(bst->root == NULL) return ;delNode(data);
}void pretraverse(LinkBST *bst) // show element one by one,(root,left,right)
{LinkNode *cur = NULL;// pointer array(stack:LIFO): array, each element is a pointer(point to node)LinkNode *arr[bst->length];int n = 1;arr[n-1] = bst->root;printf("pretravel: ");while(n != 0){cur = arr[n-1];printf("%d ", cur->value);n--;if(cur->right){arr[n] = cur->right;n++;}if(cur->left){arr[n] = cur->left;n++;}}printf("\n");
}void midtraverse(LinkBST *bst) // show element one by one,(left,root,right)
{printf("midtravel: ");LinkNode *cur = bst->root;// pointer array(stack:LIFO): array, each element is a pointer(point to node)LinkNode *arr[bst->length];int n = 0;while(cur || n != 0){if(cur){arr[n] = cur;n++;cur = cur->left;}else{cur = arr[n-1];printf("%d ", cur->value);n--;cur = cur->right;}}printf("\n");
}void posttraverse(LinkBST *bst) // show element one by one,(left,right,root)
{LinkNode *cur = NULL;// pointer array(stack:LIFO): array, each element is a pointer(point to node)LinkNode *arr[bst->length];LinkNode *brr[bst->length];int n = 1, m = 0;arr[n-1] = bst->root;while(n != 0){ cur = brr[m] = arr[n-1];n--;m++;if(cur->left){arr[n] = cur->left;n++;}if(cur->right){arr[n] = cur->right;n++;}}printf("posttravel: ");for(int i = m - 1; i >= 0; i--){printf("%d ", brr[i]->value);}printf("\n");
}void breadthtraverse(LinkBST *bst) // show element one by one,(levels)
{printf("threadtravel: ");// queue(FIFO): use Linkedlist implementQueue queue;queue.header = createQnode(bst->root);queue.tail = NULL;LinkNode *cur = NULL;while(queue.header){cur = queue.header->bstnode;printf("%d ", cur->value);popQnode(&queue);if(cur->left){addQnode(&queue, cur->left);}if(cur->right){addQnode(&queue, cur->right);}}printf("\n");
}int find(LinkNode *node, int data) // if find data,return 1(true),or return 0(false)
{LinkNode *cur = node;while(cur){if(data == cur->value) return 1;if(data < cur->value) cur = cur->left;else if(data > cur->value) cur = cur->right;}return 0;
}
// bstqueue.c
#include <stdlib.h>/* structure */
typedef struct queueNode // node of the queue
{void *bstnode; // data type is bst nodestruct queueNode *next; // point to next node
} Qnode;typedef struct queue // queue(Linkedlist)
{Qnode *header; // point to the top nodeQnode *tail; // point to the last node
} Queue;/* subfunction */
Qnode *createQnode(void *bstnode) // create a node of the queue
{Qnode *node = (Qnode *)malloc(sizeof(Qnode));if(node == NULL){perror("Memory allocation failed");exit(-1);}node->bstnode = bstnode;node->next = NULL;return node;
}void addQnode(Queue *queue, void *node) // add a element to the end of the queue
{Qnode *qnode = createQnode(node);if(queue->tail == NULL) queue->tail = queue->header = qnode;else{queue->tail->next = qnode;queue->tail = qnode;}
}void popQnode(Queue *queue) // delete a element from the top of the queue
{queue->header = queue->header->next;if(queue->header == NULL) queue->tail = NULL;
}
编译链接: gcc -o bstree bstree.c
执行可执行文件: ./bstree
相关文章:

【数据结构】(C语言):二叉搜索树(不使用递归)
二叉搜索树: 非线性的,树是层级结构。基本单位是节点,每个节点最多2个子节点。有序。每个节点,其左子节点都比它小,其右子节点都比它大。每个子树都是一个二叉搜索树。每个节点及其所有子节点形成子树。可以是空树。 …...

Fastapi在docekr中进行部署之后,uvicorn占用的CPU非常高
前一段接点小活,做点开发,顺便学了学FASTAPI框架,对比flask据说能好那么一些,至少并发什么的不用研究其他的asgi什么的,毕竟不是专业开发,能少研究一个东西就省了很多的事。 但是部署的过程中突然之间在do…...
Pandas数据可视化宝典:解锁图形绘制与样式自定义的奥秘
Pandas数据可视化宝典:解锁图形绘制与样式自定义的奥秘 引言 数据可视化是将数据以图形或图像的形式展示出来,使复杂的数据更容易被人类理解和分析。在数据分析、商业智能、科学研究等领域,数据可视化都扮演着至关重要的角色。Pandas作为一…...

2024前端面试真题【JS篇】
DOM DOM:文本对象模型,是HTML和XML文档的编程接口。提供了对文档的结构化的表述,并定义可一种方式可以使从程序中对该结构进行访问,从而改变文档的结构、样式和内容。 DOM操作 创建节点:document.createElement()、do…...

axios使用sm2加密数据后请求参数多了双引号解决方法
axios使用sm2加密数据后请求参数多了双引号解决 背景问题描述解决过程 背景 因项目安全要求,需对传给后端的入参加密,将请求参数加密后再传给后端 前期将axios降低到1.6.7后解决了问题,但最近axios有漏洞,安全要求对版本升级&…...

MybatisPlus 核心功能
MybatisPlus 核心功能 文章目录 MybatisPlus 核心功能1. 条件构造器1.1 QueryWrapper1.2 LambdaQueryWrapper(推荐)1.3 UpdateWrapper1.4 LambdaUpdateWrapper 2. 自定义SQL3. Service接口 1. 条件构造器 当涉及到查询或修改语句时,MybatisP…...
vivado EQUIVALENT_DRIVER_OPT、EXCLUDE_PLACEMENT
Vivado工具将所有逻辑上等效的信号的驱动程序合并为单个驱动程序 在逻辑优化过程中指定-merge_equivalent_drivers选项时 (opt_design)。请参阅《Vivado Design Suite用户指南:实施》中的此链接 (UG904)[参考文献20]了…...

docker也能提权??内网学习第6天 rsync未授权访问覆盖 sudo(cve-2021-3156)漏洞提权 polkit漏洞利用
现在我们来说说liunx提权的操作:前面我们说了环境变量,定时任务来进行提权的操作 rsync未授权访问覆盖 我们先来说说什么是rsync rsync是数据备份工具,默认是开启的873端口 我们在进行远程连接的时候,如果它没有让我们输入账号…...

TF卡病毒是什么?如何防范和应对?
在存储芯片及存储卡领域,TF卡病毒是一个备受关注的话题。在本文中,拓优星辰将详细解释TF卡病毒的含义、来源以及如何防范和应对这一问题,帮助客户更好地了解和处理TF卡病毒的风险。 1. TF卡病毒的含义 TF卡病毒是指针对TF存储卡(T…...
window对象监听浏览器页签之间的切换状态;前端监听浏览器切换页签的触发时机
window对象监听浏览器页签之间的切换状态 记录两种办法 第一种:会将任何鼠标点进或点出浏览器的操作监听;同页面也会触发 // 窗口获得焦点时的回调函数 function onWindowFocus() {console.log(窗口获得焦点);querySubmit() } // 窗口失去焦点时的回调函…...
MySQL 条件函数/加密函数/转换函数
条件函数 IF(): 如果条件为真,返回一个值,否则返回另一个值。 -- 示例:根据员工的薪水返回薪水等级 SELECT name, salary, IF(salary < 3000, Low, IF(salary BETWEEN 3000 AND 7000, Medium, High)) AS salary_level FROM employ…...

初学SpringMVC之接收请求参数及数据回显
pom.xml 文件导入 lombok 的依赖 <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version></dependency> Controller 表示这是一个控制器 RequestParam 表示从前端接收…...

Java链表LinkedList经典题目
一.LinkedList的方法 首先先看一下链表的方法: 方法解释boolean add(E e)尾插void add(int index, E element)将 e 插入到 index 位置boolean addAll(Collection c)尾插 c 中的元素E remove(int index)删除 index 位置元素boolean remove(Object o)删除遇到的第一…...

【cocos creator】2.x,伪3d拖拽,45度视角,60度视角,房屋装扮
伪3d拖拽,45度视角,60度视角 工程下载:(待审核) https://download.csdn.net/download/K86338236/89530812 dragItem2.t s import mapCreat2 from "./mapCreat2";const {ccclass, property } = cc._decorator; /*** 拖拽类,挂在要拖拽的节点上*/ @ccclass export…...

【thingsbord源码编译】 显示node内存不足
编译thingsbord显示报错 FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory问题原因分析 重新安装java版本 编译通过...

内存巨头SK海力士正深化与TSMC/NVIDIA合作关系,开发下一代HBM
据BusinessKorea报道,内存巨头SK海力士正深化与台积电(TSMC)及英伟达(NVIDIA)的合作关系,并计划在9月的台湾半导体展(Semicon Taiwan)上宣布更紧密的伙伴关系。 SK海力士与台积电的合作历史已久。2022年,台积电在其北美技术研讨会上宣布成立O…...
基于Pinia的WebSocket管理与优化实践(实现心跳重连机制,异步发送)
WebSocket作为一种全双工通信协议,允许服务器和客户端之间建立持久的连接,提供了比传统HTTP请求更为高效的数据交换方式。本文将探讨如何使用Pinia状态管理库在Vue应用中优雅地管理和优化WebSocket连接,以实现稳定、高效的实时数据传输。 环境…...
Perl词法作用域:自定义编程环境的构建术
🎭 Perl词法作用域:自定义编程环境的构建术 在Perl编程中,词法作用域(lexical scoping)是一种控制变量可见性的方式,它允许变量在特定的作用域内可见,从而避免变量名的冲突。Perl提供了灵活的机…...
vscode使用ssh连接远程服务器
开工啦 vscode连接远程服务器(傻瓜式教学) 正常根据上面文章的步骤就可以连接了 报错可以尝试的文章: VScode通过remote ssh连接虚拟机 & 报错过程试图写入的管道不存在(已解决) vscode remote ssh linux[血泪…...
linux 常用和不那么常用命令记录02 磁盘占用
常用的磁盘相关命令 du 有的时候我们想要查询一个文件所占用的磁盘空间大小,可以使用du命令来查看 命令 配置 参数 du [options] [files or directories]-h:以人类可读的格式显示输出(例如 KB、MB、GB)。 -s…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
Spring Boot + MyBatis 集成支付宝支付流程
Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例(电脑网站支付) 1. 添加依赖 <!…...
从实验室到产业:IndexTTS 在六大核心场景的落地实践
一、内容创作:重构数字内容生产范式 在短视频创作领域,IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色,生成的 “各位吴彦祖们大家好” 语音相似度达 97%,单条视频播放量突破百万…...