当前位置: 首页 > news >正文

无头单链表,有完整测试程序

🍟无头单链表

👻无头单链表的所有结点都存储有效信息
👻无头单链表相对带头单链表,在有些涉及更改头节点的函数上需要传二级指针

🍟头文件list.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int SLTDataType;
typedef struct SLTNode {SLTDataType data;struct SLTNode* next;
}SLTNode;void SLTPrint(SLTNode* phead);
SLTNode* BuySLTNode(SLTDataType x);
void Destroy_Method1(SLTNode** pphead);
void Destroy_Method2(SLTNode** pphead);//查
SLTNode* FindBySerialNumber(SLTNode* phead, int n);
SLTNode* FindByContent(SLTNode* phead, SLTDataType x);
//改
void ModefyNodeBySerialNumber(SLTNode* phead, int n, SLTDataType x);
void ModifyNodeByContent(SLTNode* phead, SLTDataType x1, SLTDataType x2);
//增
void PushFront(SLTNode** pphead, SLTDataType x);
void PushBack(SLTNode** pphead, SLTDataType x);void InsertFrontBySerialNumber(SLTNode** pphead, int n, SLTDataType x);
void InsertFrontByAddress(SLTNode** pphead, SLTNode* pos, SLTDataType x);
void InsertFrontByContent(SLTNode** pphead, SLTDataType x1, SLTDataType x2);void InsertBackBySerialNumber(SLTNode** pphead, int n, SLTDataType x);
void InsertBackByAddress(SLTNode* pos, SLTDataType x);
void InsertBackByContent(SLTNode* pphead, SLTDataType x1, SLTDataType x2);
//删
void PopFront(SLTNode** pphead);
void PopBack(SLTNode** pphead);void DeleteFrontNode(SLTNode** pphead, SLTNode* pos);
void DeleteNode(SLTNode** pphead, SLTNode* pos);
void DeleteAfterNode(SLTNode* pos);//测试
SLTNode* testPush_Front_Back();
void testInsertFront();
void testInsertBack();
void testPop();

🍟函数实现list.c

🥤 辅助操作函数

🍕打印链表函数

//辅助操作(打印链表,动态申请节点)
//打印链表
void SLTPrint(SLTNode* phead) {SLTNode* cur = phead;while (cur) {//当指针不为空时进入循环printf("%d->", cur->data);cur = cur->next;}printf("NULL\n");
}

🥤 创建节点,销毁链表函数

🍕创建节点函数

//2.动态申请一个节点
SLTNode* BuySLTNode(SLTDataType x) {//1.用malloc动态申请一个结点的空间SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//2.判断是否申请成功,申请失败直接退出程序if (newnode == NULL) {perror("mallocfail");exit(-1);}//3.给结点的数据域赋值为x,给指针域赋值为NULLnewnode->data = x;newnode->next = NULL;//4.返回节点的地址return newnode;
}

🍕销毁链表函数

🥓法1:先保留头节点,把后面的删完,最后删头结点

//销毁链表
//法1:先保留头节点,把后面的删完,最后删头结点
void Destroy_Method1(SLTNode** pphead) {//链表为空,无需删除assert(pphead);//先删后面,最后删头while ((*pphead)->next) {SLTNode* next = (*pphead)->next;(*pphead)->next = next->next;free(next);}free(*pphead);
}

🥓法2:从头往后删,头节点的值一直更新

//法2:从头往后删,头节点的值一直更新
void Destroy_Method2(SLTNode** pphead) {assert(pphead);SLTNode* cur = *pphead;while (cur) {SLTNode* next = cur->next;free(cur);cur = next;}*pphead = NULL;
}

🥤增删查改——查

🍕1.根据序号查找节点

序号:serial number

// 3.1根据序号查找节点
SLTNode* FindBySerialNumber(SLTNode* phead, int n) {SLTNode* cur = phead;for (int i = 1;i < n;i++) {cur = cur->next;//如果被查找结点不存在(超过链表范围),返回空指针if (cur == NULL) {return NULL;}}return cur;
}

🍕2.根据内容查找结点

//3.2根据内容查找结点
SLTNode* FindByContent(SLTNode* phead, SLTDataType x) {SLTNode* cur = phead;while (cur) {if (cur->data == x) {return cur;}cur = cur->next;}//查找不到返回空指针return NULL;
}

🥤增删查改——改

🍕1.改变节点内数据(通过序号找到被改节点)

//4.1改变节点内数据(通过序号找到被改节点) 
void ModefyNodeBySerialNumber(SLTNode* phead, int n, SLTDataType x) {SLTNode* cur = FindBySerialNumber(phead, n);cur->data = x;
}

🍕2.改变节点内数据(通过内容找到被改节点)

//4.2改变节点内数据(通过内容找到被改节点)
void ModifyNodeByContent(SLTNode* phead, SLTDataType x1, SLTDataType x2) {SLTNode* cur = FindByContent(phead, x1);cur->data = x2;
}

🥤增删查改——增

(头插,尾插,在指定节点前插,在指定节点后插)

🍕1.头插

//5.1头插
void PushFront(SLTNode** pphead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);newnode->next = *pphead;*pphead = newnode;
}

👻问:为什么数据x传参时不传指针,而头结点要传二级指针?
👻因为数据x传进来就立马通过BuySLTNode函数被放到在堆区上申请的空间中了,就算不传指针出函数作用域也不会被销毁;而头结点要从原来的链表首结点变成新结点newnode,相当于头结点pphead的值发生变化了,头结点是一个一级指针,对一级指针的修改需要二级指针

🍕2.尾插

//5.2尾插
void PushBack(SLTNode** pphead, SLTDataType x) {SLTNode* newnode = BuySLTNode(x);if (*pphead == NULL) {*pphead = newnode;//改变结构体指针,要用二级指针,一级指针只能改形参,出作用域后形参被销毁}else {SLTNode* tail = *pphead;while (tail->next != NULL) {tail = tail->next;}tail->next = newnode;}
}

🍕3.在指定结点前插入

在指定结点前插入,需要得到指定位置的前置节点。有控制循环法和前置指针法让指针停留至前置节点处,但控制循环法只能在已知插入第几个节点时用,而前置指针法可以在任何情况下用

🥓3.1通过序号指定节点

👻用到了控制for循环法

//5.3在指定结点前插入(通过序号指定节点) 
void InsertFrontBySerialNumber(SLTNode** pphead, int n, SLTDataType x) {//产生新结点并赋值SLTNode* newnode = BuySLTNode(x);SLTNode* ptmp = *pphead;//如果要在第一个结点前插入结点,就成了头插if (n == 1) {PushFront(pphead, x);return;}//将结点放入指定位置的前一个结点,指定位置不包括第一个结点for (int i = 2;i < n;i++) {ptmp = ptmp->next;if (ptmp == NULL)printf("位置不合法");}newnode->next = ptmp->next;ptmp->next = newnode;}

这个函数之所以要传二级指针是因为有头插的情况,需要调用SLTPushFront函数,但其实用一级指针,调用PushFront函数时再取一级指针的地址也行

🥓3.2内容->地址->找到结点

👻用到了while循环加前置指针法

//5.4在指定结点前插入(内容->地址->找到结点) 
//参数二pos是由test.c调用的Find函数返回的节点位置
void InsertFrontByAddress(SLTNode** pphead, SLTNode* pos, SLTDataType x) {assert(pphead);assert(pos);//头插情况if (*pphead == pos) {PushFront(pphead, x);}//非头插else {SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}SLTNode* newnode = BuySLTNode(x);newnode->next = pos;prev->next = newnode;//由于有两个指针分别控制被插入结点和前一个结点,因此这两句顺序随意}
}

🥓3.3通过内容指定节点

👻用到了while循环加前置指针法

//5.5在指定结点前插入(通过内容指定节点)void InsertFrontByContent(SLTNode** pphead, SLTDataType x1, SLTDataType x2) {SLTNode* cur = *pphead;//头插情况if (cur->data == x1) {PushFront(pphead, x2);}//非头插情况else {cur = FindByContent(*pphead, x1);SLTNode* prev = *pphead;while (prev->next != cur) {prev = prev->next;}//此时必须要第二个指针prevSLTNode* newnode = BuySLTNode(x2);newnode->next = cur;prev->next = newnode;}
}

当不借助FindByContent函数,只知道指定节点的内容时,需要进入每一个节点对比数据是否一致,这时只能用while训话加前置指针法,因为提前不知道指定位置,无法用通过控制for循环找到指定位置的前置节点

🍕4.在指定结点后插入

🥓4.1通过序号指定节点

//5.6 在指定结点后插入(通过序号指定节点)
void InsertBackBySerialNumber(SLTNode** pphead, int n, SLTDataType x) {//原链表为空if (*pphead == NULL) {SLTNode* newnode = BuySLTNode(x);*pphead = newnode;}//原链表不为空SLTNode* newnode = BuySLTNode(x);SLTNode* ptmp = *pphead;//将结点放入指定位置的后一个结点for (int i = 1;i < n;i++) {ptmp = ptmp->next;//指定节点超过最大长度,报错if (ptmp == NULL);assert(ptmp);}newnode->next = ptmp->next;ptmp->next = newnode;
}

🥓4.2内容->地址->找到节点

//5.7在指定结点后插入(内容->地址->找到节点)
//参数一pos是由test.c调用的SLTFind函数返回的节点位置
void InsertBackByAddress(SLTNode* pos, SLTDataType x) {assert(pos);SLTNode* newnode = BuySLTNode(x);newnode->next = pos->next;pos->next = newnode;
}

🥓4.3通过内容指定节点

不借助FindByContent函数

//5.8在指定结点后插入(通过内容指定节点)不借助FindByContent函数
void InsertBackByContent(SLTNode** pphead, SLTDataType x1, SLTDataType x2) {SLTNode* newnode = BuySLTNode(x2);SLTNode* cur = *pphead;//原链表为空,newnode就是头节点if (cur == NULL) {*pphead = newnode;}while (cur) {if (cur->data == x1) {//指定结点是尾结点if (cur->next == NULL) {cur->next = newnode;}//指定结点不是尾结点else {newnode->next = cur->next;cur->next = newnode;}}cur = cur->next;}//没找到return;
}

🥤增删查改——删

(头删,尾删,删除指定位置,删除指定位置的前一个节点,删除指定位置的后一个节点)

🍕1.头删

//6.1头删
void PopFront(SLTNode** pphead) {//头结点为空,报错assert(*pphead);//不为空SLTNode* newhead = (*pphead)->next;free(*pphead);*pphead = newhead;
}

🍕2.尾删

//6.2尾删
void PopBack(SLTNode** pphead) {//头结点为空,报错assert(*pphead);//只有一个结点if ((*pphead)->next == NULL) {free(*pphead);*pphead = NULL;}//有两个及以上个结点else {SLTNode* tail = *pphead;while (tail->next->next){tail = tail->next;//指向尾节点的前置节点}free(tail->next);tail->next = NULL;}
}

🍕3.删除指定节点的前一个节点

(由于前置指针法相对于控制for循环法更普适,这里只展示前置指针法)

//删除指定节点的前一个节点
void DeleteFrontNode(SLTNode** pphead, SLTNode* pos) {//指定位置不可以是头节点if (pos == *pphead) {return;}//指定位置为第二个节点,头结点被删除,更新头结点if ((*pphead)->next == pos) {PopFront(pphead);}//定义pos的前置指针prevelse {SLTNode* prevprev = *pphead;while (prevprev->next->next != pos) {prevprev = prevprev->next;}free(prevprev->next);prevprev->next = pos;}
}

🍕4.删除指定位置节点

//删除指定位置节点
void DeleteNode(SLTNode** pphead, SLTNode* pos) {//如果删除了头结点,头删函数if (pos == *pphead) {PopFront(pphead);}else {SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}prev->next = pos->next;free(pos);pos = NULL;}
}

🍕5.删除指定节点的后一个节点

//删除指定节点的后一个节点
void DeleteAfterNode(SLTNode* pos) {//检查pos是否为空assert(pos);//检查pos是否是尾节点assert(pos->next);SLTNode* posNext = pos->next;pos->next = posNext->next;free(posNext);posNext = NULL;
}

🍟测试函数test.c

🥤测试头插尾插

SLTNode* testPush_Front_Back() {//测试头插PushFrontprintf("请输入头插长度:");int n = 0;scanf("%d", &n);printf("请依次输入结点的值:\n");SLTNode* plist = NULL;for (int i = 0;i < n;i++) {int val = 0;scanf("%d", &val);PushFront(&plist, val);}SLTPrint(plist);//测试尾插printf("请输入尾插长度:");int m = 0;scanf("%d", &m);printf("请依次输入结点的值:\n");for (int i = 0;i < m;i++) {int val = 0;scanf("%d", &val);PushBack(&plist, val);}SLTPrint(plist);return plist;
//销毁链表Destroy_Method1(&plist);//Destroy_Method2(&plist);
}

🥤测试在指定节点前插入

void testInsertFront() {SLTNode* plist = testPush_Front_Back();//在指定结点前插入(通过序号指定节点)printf("在指定结点前插入(通过序号指定节点)\n");printf("请输入结点编号:");int input1 = 0;scanf("%d", &input1);printf("请输入插入的数据");SLTDataType data1 = 0;scanf("%d", &data1);InsertFrontBySerialNumber(&plist, input1, data1);SLTPrint(plist);//在指定结点前插入(内容->地址->找到结点)printf("在指定结点前插入(内容->地址->找到结点)\n");printf("请输入要插入位置的数据:");SLTDataType data2 = 0;scanf("%d", &data2);SLTNode* pos = FindByContent(plist, data2);printf("请输入插入的数据:");SLTDataType data3 = 0;scanf("%d", &data3);InsertFrontByAddress(&plist, pos, data3);SLTPrint(plist);//在指定结点前插入(通过内容指定节点)printf("在指定结点前插入(通过内容指定节点)\n");printf("请输入要插入位置的数据:");SLTDataType data4 = 0;scanf("%d", &data4);printf("请输入插入的数据:");SLTDataType data5 = 0;scanf("%d", &data5);InsertFrontByContent(&plist, data4, data5);SLTPrint(plist);//销毁链表Destroy_Method1(&plist);//Destroy_Method2(&plist);
}

🥤测试在指定节点后插入

void testInsertBack() {SLTNode* plist = testPush_Front_Back();//在指定结点后插入(通过序号指定节点)printf("在指定结点后插入(通过序号指定节点)\n");printf("请输入节点编号:");int input2 = 0;scanf("%d", &input2);printf("请输入插入的数据:");SLTDataType data6 = 0;scanf("%d", &data6);InsertBackBySerialNumber(&plist, input2, data6);SLTPrint(plist);//在指定结点后插入(内容->地址->找到结点)printf("在指定结点后插入(内容->地址->找到结点)\n");printf("请输入要插入位置的数据:");SLTDataType data7 = 0;scanf("%d", &data7);SLTNode* pos = FindByContent(plist, data7);printf("请输入插入的数据:");SLTDataType data8 = 0;scanf("%d", &data8);InsertBackByAddress(pos, data8);SLTPrint(plist);//在指定结点后插入(通过内容指定节点)printf("在指定结点后插入(通过内容指定节点)\n");printf("请输入要插入位置的数据:");SLTDataType data9 = 0;scanf("%d", &data9);printf("请输入插入的数据:");SLTDataType data10 = 0;scanf("%d", &data10);InsertBackByContent(&plist, data9, data10);SLTPrint(plist);//销毁链表Destroy_Method1(&plist);//Destroy_Method2(&plist);
}

🥤测试各种删除

void testPop() {SLTNode* plist = testPush_Front_Back();//测试头删printf("测试头删\n");PopFront(&plist);SLTPrint(plist);//测试尾删printf("测试尾删\n");PopBack(&plist);SLTPrint(plist);//删除指定节点的前一个节点printf("删除指定节点的前一个节点\n");printf("请输入指定节点内容:\n");SLTDataType data11 = 0;scanf("%d", &data11);SLTNode* pos1 = FindByContent(plist, data11);DeleteFrontNode(&plist, pos1);SLTPrint(plist);//删除指定位置节点printf("删除指定位置节点\n");printf("请输入指定节点内容:\n");SLTDataType data12 = 0;scanf("%d", &data12);SLTNode* pos2 = FindByContent(plist, data12);DeleteNode(&plist, pos2);SLTPrint(plist);//删除指定节点的后一个节点printf("删除指定节点的后一个节点\n");printf("请输入指定节点内容:\n");SLTDataType data13 = 0;scanf("%d", &data13);SLTNode* pos3 = FindByContent(plist, data13);DeleteAfterNode(pos3);SLTPrint(plist);//销毁链表Destroy_Method1(&plist);//Destroy_Method2(&plist);}

🥤主函数

测一个的时候其他三个注释掉,要不然会累死的O(∩_∩)O哈哈~😂

int main() {testPush_Front_Back();testInsertFront();testInsertBack();testPop();
}

🍟测试结果

🥤测试一:头插尾插

在这里插入图片描述

🥤测试二:在指定节点前插入节点

在这里插入图片描述

🥤测试三:在指定节点后插入节点

在这里插入图片描述

🥤测试四:各种删除

在这里插入图片描述
👻当前是有点小缺陷的,当通过指定内容找到节点时,如果遇到有多个相同数据的情况,会在第一个出现该数据的位置停下进行插入等操作,这是由于当前节点中的数据只是一个简单的数字,当以后节点内数据更多或每个节点都有自己的唯一标识时,就不会有这个缺陷了。

🌈把以上所有代码块连起来就是完整程序啦,最开始是头文件list.h,接下来是函数实现list.c,最后是测试文件test.c,其中分了4个函数。

🌈在插入和删除那块函数有点多,我把想到的全写上了,有点繁琐,大家主要借鉴思路哈🤣😂,如有错误请及时指正,感谢❤️

相关文章:

无头单链表,有完整测试程序

&#x1f35f;无头单链表 &#x1f47b;无头单链表的所有结点都存储有效信息 &#x1f47b;无头单链表相对带头单链表&#xff0c;在有些涉及更改头节点的函数上需要传二级指针 &#x1f35f;头文件list.h #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #includ…...

2023年第四届“华数杯”数学建模思路 - 案例:FPTree-频繁模式树算法

## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c;他与Apriori算法一样也是用来挖掘频繁项集的&#xff0c…...

MySQL做分布式锁

分布式锁mysql实现方式 方式1&#xff1a;唯一索引 创建锁表&#xff0c;内部存在字段表示资源名及资源描述&#xff0c;同一资源名使用数据库唯一性限制。多个进程同时往数据库锁表中写入对某个资源的占有记录&#xff0c;当某个进程成功写入时则表示其获取锁成功其他进程由于…...

Python学习笔记:变量类型、字符串基本操作

1.注释 单行注释 # 单行注释 多行注释 """ 多行注释 """2.变量类型 # 基本变量类型 a 1 # integer b 1.5 # float c string # String d "string" # string e False # boolean # list\tuple\dictionar…...

JVM的组件、自动垃圾回收的工作原理、分代垃圾回收过程、可用的垃圾回收器类型

详细画的jvm模型图 https://www.processon.com/diagraming/64c8aa11c07d99075d934311 官方网址 https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html 相关概念 年轻代是所有新对象被分配和老化的地方。当年轻代填满时&#xff0c;这会导致m…...

【elementui】解决el-select组件失去焦点blur事件每次获取的是上一次选中值的问题

目录 【问题描述】 【问题摘要】 【分析问题】 【完整Test代码】 【封装自定义指令】 ↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~ 【问题描述】 一位朋友遇到这么一个开发场景&#xff1a;在表格里面嵌入el-…...

通过了PMP考试,还有什么证书值得考?

自从7月24号公布了PMP成绩后&#xff0c;不少伙伴私信小编&#xff1a;通过PMP后还有哪些证书可以提升自己&#xff1f;一来是多份高含金量的证书可以多点竞争力&#xff0c;二来是加持自己的职业发展&#xff01;今天小编就来给大家捋一捋&#xff01; 一.NPDP认证 2016 年 4…...

页面技术基础-html

页面技术基础-html 环境准备&#xff1a;在JDBC中项目上完成代码定义 1. 新建一个 Module:filr->右键 -》Module -》Java-》next->名字(html_day1)->finish 2. 在 Moudle上右键-》第二个选项&#xff1a;add framework .. -> 选择JavaEE下第一个选项 Web Apllicat…...

/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28‘ not found

某项目中&#xff0c;我要给别人封装一个深度学习算法的SDK接口&#xff0c;运行在RK3588平台上&#xff0c;然后客户给我的交叉编译工具链是 然后我用他们给我的交叉编译工具链报下面的错误&#xff1a; aarch64-buildroot-linux-gnu-gcc --version /data/chw/aarch64/bin/cca…...

解决SVN或GIT忽略提交文件的问题

背景 使用IDEA 的SVN插件提交文件是总是会提交一些不需要提交的文件; 我们可以通过一些简单设置忽略这些文件。 git 在项目根目录新建文本文件&#xff0c;修改后缀为.gitignore 文件中添加内容 *.iml .project .gradle/ .idea/ target/ build/ .vscode/ .settings/ .facto…...

Django框架之路由用法

简介 路由简单的来说就是根据用户请求的 URL 链接来判断对应的处理程序&#xff0c;并返回处理结果&#xff0c;也就是 URL 与 Django 的视图建立映射关系。 Django 路由在 urls.py 配置&#xff0c;urls.py 中的每一条配置对应相应的处理方法。 Django 不同版本 urls.py 配…...

回文链表 LeetCode热题100

题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 思路 利用快慢指针找到链表中间节点&#xff0c;反转后半段链表。前半段从头节点开始与后半段比较。 注意当链表节点…...

如何在群晖NAS中使用cpolar内网穿透

如何在群晖nas中使用cpolar内网穿透 文章目录 如何在群晖nas中使用cpolar内网穿透 今天&#xff0c;我们来为大家介绍&#xff0c;如何在群晖系统中&#xff0c;使用图形化界面的cpolar。 cpolar经过图形化改造后&#xff0c;使用方法已经简便了很多&#xff0c;基本与其他应用…...

无头单向不循环链表和带头双向循环链表的创建

Lei宝啊&#xff1a;个人主页 愿所有美好不期而遇 前言&#xff1a; 接下来我们将会了解最基础的链表--->单链表 以及最方便也是最爽的链表--->带头双向循环链表。 若有看不懂之处&#xff0c;可画图或者借鉴这里&#xff1a;反转单链表&#xff0c;对于数据结构而言&am…...

超简单的fastapi链接websocket用例

main.py from typing import Listfrom fastapi import FastAPI, WebSocket, WebSocketDisconnectapp FastAPI()class ConnectionManager:def __init__(self):# 存放激活的ws连接对象self.active_connections: List[WebSocket] []async def connect(self, ws: WebSocket):# 等…...

MySQL详解

目录 一、MySQL 概述二、MySQL 安装和配置三、MySQL 基础语法四、MySQL 高级语法五、MySQL 性能优化六、MySQL 应用场景和实例七、MySQL 开发工具和插件八、MySQL 学习资源和社区 一、MySQL 概述 MySQL 是一种开源的关系型数据库管理系统&#xff0c;最初由瑞典的 MySQL AB 公…...

Vue [Day2]

指令修饰符 v-model.trim v-model.number 事件名.stop click.stop 事件名.prevent keyup.enter <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…...

【前端|Javascript第1篇】一文搞懂Javascript的基本语法

欢迎来到JavaScript的奇妙世界&#xff01;作为前端开发的基石&#xff0c;JavaScript为网页增色不少&#xff0c;赋予了静态页面活力与交互性。如果你是一名前端小白&#xff0c;对编程一无所知&#xff0c;或者只是听说过JavaScript却从未涉足过&#xff0c;那么你来对了地方…...

【Linux命令200例】cp用于复制文件和目录(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜…...

C高级_第二讲_shell指令和shell脚本_递归练习

思维导图 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位 int funh(int num){if(0 num){return 0;}else{funh(num/10);printf("%d\n", num%10);} }int main(int argc, const char *argv[]) {puts("请输入一个数");int num 0;scanf(&quo…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南

&#x1f680; C extern 关键字深度解析&#xff1a;跨文件编程的终极指南 &#x1f4c5; 更新时间&#xff1a;2025年6月5日 &#x1f3f7;️ 标签&#xff1a;C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言&#x1f525;一、extern 是什么&#xff1f;&…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...