04 单链表

目录

  1. 链表的概念和结构
  2. 单链表
  3. OJ练习

1. 链表的概念和结构

1.1 链表的概念

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的

在这里插入图片描述1.从上图可以看出链式结构在逻辑上是连续的,物理上不一定连续
2.现实中的节点一般都是从堆上申请出来的
3.从堆上申请的空间,是按照一定的策略来分配的,两次申请的空间可能连续,也可能不连续

1.2 链表的分类

以下情况组合起来可能有8种链表结构

1.单向或者双向
在这里插入图片描述
2.带头或者不带头
在这里插入图片描述

3.循环或非循环
在这里插入图片描述
虽然有这么多链表结构,但我们常用的还是两种结构

无头单向非循环链表
在这里插入图片描述带头双向循环
在这里插入图片描述1.无头单向非循环链表:结构简单,一般一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现更多

2.带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现

2. 单链表

头文件

#pragma once//数据类型
typedef int DataType;
//结构
typedef struct _SListNode
{DataType data;struct _SListNode* pNext;
}SListNode;//插入
void PushFront(SListNode** pHead, DataType data);
void PushBack(SListNode** pHead, DataType data);
//pos之前插入
void Insert(SListNode** pHead, SListNode* pPos, DataType data);
//pos之后插入
void InsertAfter(SListNode** pHead, SListNode* pPos, DataType data);
//查找
SListNode* Find(SListNode* pHead, DataType data);
//删除
void PopFront(SListNode** pHead);
void PopBack(SListNode** pHead);
void Erase(SListNode** pHead, SListNode* pos);
// 删除pos位置后面的值
void EraseAfter(SListNode* pos);//打印
void PrintList(SListNode* pHead);
//销毁
void Destory(SListNode** pHead);

实现文件

#include "SList.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>SListNode* BuyNode(DataType data)
{//创建新节点SListNode* NewNode = (SListNode*)malloc(sizeof(SListNode));if (NewNode == NULL){perror("malloc fail");return NULL;}NewNode->data = data;NewNode->pNext = NULL;return NewNode;
}void PushFront(SListNode** pHead, DataType data)
{//新节点SListNode* NewNode = BuyNode(data);//连接NewNode->pNext = *pHead;*pHead = NewNode;
}void PushBack(SListNode** pHead, DataType data)
{SListNode* NewNode = BuyNode(data);	//分情况,如果链表为空if (*pHead == NULL){*pHead = NewNode;}else{//找链表尾SListNode* pTail = *pHead;while (pTail->pNext != NULL){pTail = pTail->pNext;}pTail->pNext = NewNode;}}void Insert(SListNode** pHead, SListNode* pPos, DataType data)
{assert(pHead);assert(pPos);//记录当前节点SListNode* pCur = *pHead;//插入位置为第一个节点,头插if (pCur == pPos){PushFront(pHead, data);}else{//找pos位置链接while (pCur->pNext != pPos){pCur = pCur->pNext;}SListNode* NewNode = BuyNode(data);NewNode->pNext = pPos;pCur->pNext = NewNode;}}void InsertAfter(SListNode** pHead, SListNode* pPos, DataType data)
{assert(pPos);//直接将pos位置链接SListNode* NewNode = BuyNode(pHead);NewNode->pNext = pPos->pNext;pPos->pNext = NewNode;
}SListNode* Find(SListNode* pHead, DataType data)
{SListNode* pCur = pHead;while (pCur != NULL){if (pCur->data == data)return pCur;pCur = pCur->pNext;}return NULL;
}void PopFront(SListNode** pHead)
{assert(*pHead);//记录释放指针SListNode* pDel = *pHead;//移动链表首节点*pHead = pDel->pNext;free(pDel);
}void PopBack(SListNode** pHead)
{assert(*pHead);//记录释放指针//如果只有一个节点,需要将链表置空if ((*pHead)->pNext == NULL){free(*pHead);*pHead = NULL;}else{//找链表尾SListNode* pTail = *pHead;while (pTail->pNext->pNext != NULL){pTail = pTail->pNext;}free(pTail->pNext);pTail->pNext = NULL;}}void Erase(SListNode** pHead, SListNode* pos)
{assert(pHead);assert(pos);//删第一个节点,头删if (*pHead == pos){PopFront(pHead);}else{//找pos位置SListNode* pPrev = *pHead;while (pPrev->pNext != pos){			pPrev = pPrev->pNext;}pPrev->pNext = pos->pNext;free(pos);}}void EraseAfter(SListNode* pos)
{assert(pos);assert(pos->pNext);//断开pos位置SListNode* Del = pos->pNext;pos->pNext = Del->pNext;free(Del);
}void PrintList(SListNode* pHead)
{SListNode* pCur = pHead;while (pCur != NULL){printf("%d ", pCur->data);pCur = pCur->pNext;}printf("\n");
}
//一级指针无需断言,需要在调用后置空
void Destory(SListNode** pHead)
{assert(pHead);SListNode* cur = *pHead;SListNode* del = NULL;while (cur != NULL){del = cur;cur = cur->pNext;free(del);}*pHead = NULL;
}

主文件

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "SList.h"
int main()
{//SListNode* pList = NULL;//插入//PushFront(&pList, 3);//PushFront(&pList, 2);//PushFront(&pList, 1);//PushBack(&pList, 4);//PushBack(&pList, 5);//PrintList(pList);//删除//PopFront(&pList);//PopBack(&pList);//PrintList(pList);//Insert();//SListNode* p = Find(pList, 3);//Insert(&pList, p, 8);//PrintList(pList);//InsertAfter(&pList, p, 9);//EraseAfter(p);//PrintList(pList);return 0;
}

单链表的实现中需要注意的问题,一个是如果需要改变链表的指针位置,则需要传入二级指针。不用二级指针则需要返回新的头。assert需要断言的地方有哪些,如果操作会崩溃的地方必须断言,断言是一种严厉的检查,if判断则是温柔的检查。

在插入和删除等这些操作的时候,需要考虑只有一个节点的情况,如果传入节点可以为空,也要考虑为空的情况,pos位置的合理性也需要断言或考虑在内

在插入的时候也有一种取巧的办法,将新节点和前一个节点的值直接替换,这样在之前插入只需要遍历一次

3. OJ练习

3.1 移除元素

移除链表元素:https://leetcode.cn/problems/remove-linked-list-elements/description/

在这里插入图片描述

解析
这个考虑的是链表的删除操作,需要一前一后两个指针才能删除当前节点。同时,不要忘了考虑只有一个节点,头删的情况

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* pPrev = NULL;struct ListNode* pCur = head;while (pCur != NULL)
{if (pCur->val == val){//判断是不是第一个节点if (pCur == head){//头删pCur = pCur->next;free(head);head = pCur;}else{//不是头删,移除元素pPrev->next = pCur->next;free(pCur);pCur = pPrev->next;}}else{pPrev = pCur;pCur = pCur->next;}}return head;
}

另一种思路,可以将不是6的元素放入新链表尾插,然后返回新的链表头。需要考虑第一个节点的情况和每次插入后下节点置空

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* pCur = head;struct ListNode* NeoHead = NULL;struct ListNode* tail = NULL;while (pCur != NULL) {//不是该值的放入新链表if (pCur->val != val) {if (tail == NULL) {NeoHead = pCur;} else {tail->next = pCur;}tail = pCur;pCur = pCur->next;}//是该值释放else {struct ListNode* del = pCur;pCur = pCur->next;free(del);}//第一个节点或空链表tail不能置空if (tail != NULL) {//最后一个节点断掉tail->next = NULL;}}return NeoHead;
}

3.2 反转单链表

反转链表: https://leetcode.cn/problems/reverse-linked-list/description/

在这里插入图片描述

解析
两种思路大体差不多,第一种是将每个节点的指向反过来,第二种是每拿到一个节点直接头插。这里演示第二种思路,可以少一些判断

在这里插入图片描述

需要三个变量,cur和newhead用来头插交换指向,newhead记录新的头节点,next记录下一个用来插入的元素

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* reverseList(struct ListNode* head) {struct ListNode* newhead = NULL;struct ListNode* cur = head;while(cur != NULL){//记录下一个插入的元素struct ListNode* next = cur->next;//头插cur->next = newhead;//移动头节点newhead = cur;//迭代cur = next;}return newhead; 
}

3.3 中间节点

链表中间节点https://leetcode.cn/problems/middle-of-the-linked-list/

第一种思路:
遍历求出链表长度返回需要的中间节点的链表

第二种思路:
慢指针每次走一步,快指针每次走两步,当快指针走完的时候,慢指针刚好走了链表一半,画图来分开链表奇数个和偶数个的情况

在这里插入图片描述

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head;struct ListNode* fast = head;while(fast != NULL && fast->next != NULL){slow = slow->next;fast = fast->next->next;}return slow;
}

3.4 倒数第k节点

链表倒数第k个节点:https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&&tqId=11167&rp=2&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking

在这里插入图片描述

第一个方法: 求链表总长度,减去k就知道返回哪个节点的值
第二个方法:和上面思路一样,用一个快慢指针,让两个指针拉开差距,返回第k个节点就让快指针走几步,然后同时移动两个指针,直到快指针为空返回慢指针的值

在这里插入图片描述

其中有两点需要判断,如果传入的是空指针返回空,如果快指针在拉开距离的时候是空,说明要返回的值超出链表范围,也返回空

/*** struct ListNode {*  int val;*  struct ListNode *next;* };*//**** @param pListHead ListNode类* @param k int整型* @return ListNode类*/
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {// write code herestruct ListNode* slow = pListHead;struct ListNode* fast = pListHead;//空链表if (pListHead == NULL) {return NULL;}while (k > 0) {//快指针为空,返回空if (fast == NULL)return NULL;fast = fast->next;k--;}while (fast != NULL) {slow = slow->next;fast = fast->next;}return slow;}

3.5 合成链表

合并两个有序链表:https://leetcode.cn/problems/merge-two-sorted-lists/description/

在这里插入图片描述

将两个列表的元素挨个比较,较小的插入新链表。首先需要判断两个链表中可能有一个或两个链表都为空的情况,如果其中一个是空链表,直接返回另一个即可。在插入的过程中需要判断是不是第一个节点的情况,也就是新链表第一次插入。最后有一个链表迭代后为空时,需要将尾巴与另一个链表连接上

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {//如果有一个链表为空,返回另一个if(list1 == NULL)return list2;if(list2 == NULL)return list1;struct ListNode* newnode = NULL;struct ListNode* tail = NULL;while (list1 != NULL && list2 != NULL) {if (list1->val <= list2->val) {//是不是第一个节点if (tail == NULL) {newnode = list1;tail = list1;} else {tail->next = list1;tail = list1;}list1 = list1->next;} else {//同上if (tail == NULL) {newnode = list2;tail = list2;} else {tail->next = list2;tail = list2;}list2 = list2->next;}}//一个链表走完,链接另一个if (list1 == NULL) {tail->next = list2;}if (list2 == NULL) {tail->next = list1;}return newnode;
}

3.6 链表分割

链表分割https://www.nowcoder.com/practice/0e27e0b064de4eacac178676ef9c9d70?tpId=8&&tqId=11004&rp=2&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

在这里插入图片描述
约瑟夫环,所与人围成一个圈,数到3或数到4的人自杀,什么位置才能让自己幸存到最后一个
用数组解决,挪动删除比较麻烦,所以可以直接用标记-1为已经删除的。这种更适合用链表做,删除必剪方便

思路
可以用两个链表,为了保证数据的顺序不变,将这个值大和小的节点分别尾插到两个链表。在最后,要把后面的链表尾置空,不然会循环起来。可以设置哨兵位,也可以不设置,头节点的尾插会方便很多

不带哨兵位

 ListNode* partition(ListNode* pHead, int x) {// write code here//记录链表头和当前链表尾ListNode* list1 = NULL;ListNode* cur1 = NULL;ListNode* list2 = NULL;ListNode* cur2 = NULL;ListNode* cur = pHead;while (cur != NULL) {//插入第一个链表if (cur->val < x) {//第一次插入if (list1 == NULL) {list1 = cur;} else {cur1->next = cur;}cur1 = cur;} else {if (list2 == NULL) {list2 = cur;} else {cur2->next = cur;}cur2 = cur;}cur = cur->next;}//链表为空的三种情况,分别将尾节点置空if (list1 == NULL) {cur2->next = NULL;return list2;} else if (list2 == NULL) {cur1->next = NULL;return list1;} else {cur1->next = list2;cur2->next = NULL;return list1;}}

带哨兵位

ListNode* partition(ListNode* pHead, int x) {// write code here\
//两个链表的哨兵位和尾结点,哨兵位不存数据ListNode* head1 = NULL;ListNode* head2 = NULL;ListNode* tail1 = NULL;ListNode* tail2 = NULL;head1 = tail1 = (ListNode*)malloc(sizeof(struct ListNode));head2 = tail2 = (ListNode*)malloc(sizeof(struct ListNode));ListNode* cur = pHead;while (cur != NULL) {//判断大小插入哪个链表if (cur->val < x) {tail1->next = cur;tail1 = cur;} else {tail2->next = cur;tail2 = cur;}cur = cur->next;}//链接两个链表tail1->next = head2->next;//尾结点置空tail2->next = NULL;//更新头节点到第一个链表pHead = head1->next;//释放资源free(head1);free(head2);return pHead;}

3.7 回文结构

链表的回文结构:https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId=49&&tqId=29370&rp=1&ru=/activity/oj&qru=/ta/2016test/question-ranking

在这里插入图片描述

思路
先找到链表的中间节点将后面的逆置,从中间节点开始和头部不断向后比。可以利用前面做过的逆置和中间节点的题

 struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head;struct ListNode* fast = head;while (fast != NULL && fast->next != NULL) {slow = slow->next;fast = fast->next->next;}return slow;}struct ListNode* reverseList(struct ListNode* head) {struct ListNode* newhead = NULL;struct ListNode* cur = head;while (cur != NULL) {//记录下一个插入的元素struct ListNode* next = cur->next;//头插cur->next = newhead;//移动头节点newhead = cur;//迭代cur = next;}return newhead;}bool chkPalindrome(ListNode * A) {// write code hereListNode* mid = middleNode(A);ListNode* rmid = reverseList(mid);ListNode* fast = A;while (rmid != NULL) {if(A->val != rmid->val)return false;//迭代A= A->next;rmid = rmid->next;}return true;}

3.8 相交

相交链表:https://leetcode.cn/problems/intersection-of-two-linked-lists/description/

在这里插入图片描述
思路
如何判断两个链表有没有相交,可以看两个链表的尾节点是不是一样,因为一个节点不能指向两个节点,所以相交的链表尾结点是一样的。计算出两个链表的长度,让长的链表先走两个的差值,这样再同时走就能找到相交的节点了

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {//记录尾结点struct ListNode * tail1 = headA;struct ListNode * tail2 = headB;//记录长度int len1 = 0;int len2 = 0;//题干链表不是空链表,所以可以直接判断下一个节点while(tail1->next != NULL){tail1 = tail1->next;len1++;}while(tail2->next != NULL){tail2 = tail2->next;len2++;}//有没有交点if(tail1 != tail2){return NULL;}int gap = abs(len1 - len2);//短的移动struct ListNode * shortlist = headA;struct ListNode * longlist = headB;while(gap--){if(len1 > len2)shortlist = shortlist->next;elselonglist = longlist->next;}//找交点返回while(shortlist != longlist){shortlist = shortlist->next;longlist = longlist->next;}return shortlist;
}

3.9 环形链表

是否环形: https://leetcode.cn/problems/linked-list-cycle/description/

分析
环形链表的一些图示
在这里插入图片描述当进入到环形里就会不断绕着环转圈,要想看是不是环形链表,就看它遍历后的节点是否会重复,直接判断有些麻烦。可以用快慢指针,如果是环形,快指针肯定会和慢指针相遇,快指针可以一次走n步,每走一步判断是否和慢指针相等。为了方便,这里快指针一次走两步,原因在下面说明

bool hasCycle(struct ListNode *head) {struct ListNode * slow =head;struct ListNode * fast = head;//走到空或只有一个节点结束while(fast != NULL && fast->next != NULL){slow = slow->next;fast = fast->next->next;if(slow == fast)return true; }return false;
}

为什么快指针走两步,慢指针走一步就可以
当链表是有环的,快指针先进环,慢指针后进环。当慢指针刚进时,就可能相遇,最差的情况两个指针距离刚好走了环的长度。假设两个指针都进环时距离是N,快指针每走两步就是N+2,慢指针就是N+1,两个相减后,就是距离缩小了一步,这样循环下去,总会有追上的时候

如果快指针走N步,3步5步行不行
这种情况就会有可能一直追不上,还是上面的N,N+3减去N+1,走3步距离每次缩小两步,当之间的距离只有一步时,如果不是快指针每走一步就判断的话就会错过。因为他们的距离每次缩短N-2,可能会越过某一点。就会分环内总长度是奇数还是偶数,如果是奇数,就可能会一直错过

在这里插入图片描述

3.10 环链表环节点

返回环形链表入环第一个节点:https://leetcode.cn/problems/linked-list-cycle-ii/description/

在这里插入图片描述

思路
第一种:
假设快指针每次走两步,慢指针每次走一步。链表头到入环点的距离为L,环型的长度是C,慢指针入环后走的距离是N,慢指针走的总路程L + N,因为不存在会错过的情况,所以快指针必然在一圈内追上慢指针。快指针总路程为L + n * C + N,快指针在相遇时可能已经走了n圈,下图所示:

在这里插入图片描述

因为每次走两步,所以快指针的总路程是慢指针的2倍,所以有公式:
2(L+N)= L+N+nC
L和N移到左边减去有:
L+N = n
C
L = n*C - N
可以理解为: L=(n-1) * (C- N)
C-N的部分刚好是入口点到meet的长度,所以L的长度和meet移动C-N后刚好是入口点

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode * slow =head;struct ListNode * fast = head;//走到空或只有一个节点结束while(fast != NULL && fast->next != NULL){slow = slow->next;fast = fast->next->next;if(slow == fast){//定义相遇节点struct ListNode * meet = slow;//没遇到继续走while(head != meet){meet = meet->next;head = head->next;}return meet;}}return false;
}

第二种思路:
在这里插入图片描述
将环内从meet的next处断开,看为新的链表头,和head这个链表找交点,就是入口点

struct ListNode *detectCycle(struct ListNode *head) {struct ListNode * slow =head;struct ListNode * fast = head;//走到空或只有一个节点结束while(fast != NULL && fast->next != NULL){slow = slow->next;fast = fast->next->next;if(slow == fast){//定义新链表,尾节点为slowstruct ListNode * meet = slow->next;struct ListNode * tail1 = meet;int len1 = 0;//长链表先走while(tail1 != slow){tail1 = tail1->next;len1++;}struct ListNode * tail2 = head;int len2 = 0;while(tail2 != slow){tail2 = tail2->next;len2++;}int gap = abs(len1 - len2);while(gap--){if(len1 > len2){meet = meet->next;}else{head = head->next;}}//同时走找第一个交点while(head != meet){head =head->next;meet= meet->next;}return meet;}}return NULL;
}

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

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

相关文章

Docker(十)Docker Compose

作者主页&#xff1a; 正函数的个人主页 文章收录专栏&#xff1a; Docker 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01; Docker Compose 项目 Docker Compose 是 Docker 官方编排&#xff08;Orchestration&#xff09;项目之一&#xff0c;负责快速的部署分布式…

Vue diff原理

✨ 专栏介绍 在当今Web开发领域中&#xff0c;构建交互性强、可复用且易于维护的用户界面是至关重要的。而Vue.js作为一款现代化且流行的JavaScript框架&#xff0c;正是为了满足这些需求而诞生。它采用了MVVM架构模式&#xff0c;并通过数据驱动和组件化的方式&#xff0c;使…

Golang leetcode28 找出字符串中第一个匹配项的下标 KMP算法详解

文章目录 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题暴力求解使用KMP模式匹配算法KMP算法简述 KMP算法的代码实现 找出字符串中第一个匹配项的下标 leetcode28 串的模式匹配问题 暴力求解 func strStr(haystack string, needle string) int { L : len(need…

wayland(wl_shell) + egl + opengles 最简实例

文章目录 前言一、ubuntu 上相关环境准备1. ubuntu 上安装 weston2. 确定ubuntu 上安装的opengles 版本3. 确定安装的 weston 是否支持 wl_shell 接口二、窗口管理器接口 wl_shell 介绍二、代码实例1.egl_wayland_demo.c2. 编译和运行2.1 编译2.2 运行总结参考资料前言 本文主…

UE5 C++学习笔记 FString FName FText相互转换

1.FString 是UE里的String。最接近std::string, 唯一可以修改的字符串类型。性能更低 TEXT(string) TEXT宏&#xff0c;作用是将字符串转换成Unicode&#xff0c;切记UE中使用字符串输出要使用该宏 2. FName 是UE里特有的类型。它更注重于表示名称不区分大小写&#xff0c;不…

基于taro搭建小程序多项目框架,记重点了!!!

前言 为什么需要这样一个框架&#xff0c;以及这个框架带来的好处是什么&#xff1f; 从字面意思上理解&#xff1a;该框架可以用来同时管理多个小程序&#xff0c;并且可以抽离公用组件或业务逻辑供各个小程序使用。当你工作中面临这种同时维护多个小程序的业务场景时&#…

web架构师编辑器内容-完成属性设置的优化

对于业务组件来说&#xff0c;其属性是有很多的&#xff0c;如果把所有属性都平铺在页面上&#xff0c;就会非常长&#xff0c;而且想要更改其中的某些属性&#xff0c;可能需要向下滚动很久才能找到&#xff0c;对于UI的交互不是很友好&#xff0c;需要对属性的不同特性进行分…

KDJ指标的算法、原理和特性

KDJ的完整中文名称是随机摆动指标&#xff0c;是短线交易者最常用的指标之一。作为应用最广泛的指标之一&#xff0c;KDJ的用法网上随处可见&#xff0c;但大部分介绍都只会告诉你超买超卖&#xff0c;金叉死叉&#xff0c;详细点的讲讲背离和钝化&#xff0c;至于为什么这么用…

填空题如何去掉答案?教你3个去除小妙招

填空题如何去掉答案&#xff1f;在日常学习过程中&#xff0c;将写过的试卷填空题去掉答案&#xff0c;是一种非常有效的学习方法&#xff0c;可以帮助学生们更好地巩固和扩充知识点。首先&#xff0c;去掉答案可以让学生们重新审视题目&#xff0c;加深对知识点的理解。其次&a…

【RT-DETR有效改进】Google | EfficientNetV2一种超轻量又高效的网络 (轻量化网络)

前言 大家好&#xff0c;我是Snu77&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持Re…

鸿蒙开发笔记(二十): 常用组件 TextInput/TextArea, 弹窗,视频播放Video

1. 文本输入 TextInput/TextArea TextInput为单行输入框、TextArea为多行输入框。通过以下接口来创建。 TextArea(value?:{placeholder?: ResourceStr, text?: ResourceStr, controller?: TextAreaController})TextInput(value?:{placeholder?: ResourceStr, text?: R…

小型洗衣机怎么用?实用的迷你洗衣机推荐

由于我们的内衣、内裤和袜子等等贴身小件衣物的清洁频率比一般的衣物要高。而且&#xff0c;如果我们人工手洗的话&#xff0c;不仅会大大浪费了我们的时间&#xff0c;而且还不能进行对这些贴身的以为进行深层消毒和除菌。这种情况下&#xff0c;就得需要一台专门用于清洗内衣…

数据结构·顺序表应用

本节应用是要用顺序表实现一个通讯录&#xff0c;收录联系人的姓名、性别、电话号码、住址、年龄 ​​​​​​​ 顺序表的实现在上一节中已经完成了&#xff0c;本节的任务其实就是应用上节写出来的代码的那些接口函数功能&#xff0c;做出来一个好看的&#xff0c;可…

晨控CK-FR03-EC与欧姆龙NX系列EtherCAT通讯连接说明手册

晨控CK-FR03-EC与欧姆龙NX系列EtherCAT通讯连接说明手册 晨控CK-FR03-EC是一款基于射频识别技术的高频RFID标签读卡器&#xff0c;读卡器工作频率为13.56MHZ&#xff0c;支持对I-CODE 2、I-CODE SLI等符合ISO15693国际标准协议格式标签的读取。 读卡器同时支持标准工业通讯协…

【Linux C | 进程】进程环境 | 什么是进程?进程的开始、终止、存储空间布局、命令行参数、环境变量

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

OPC UA网关BL121 支持Modbus转OPC UA协议转换

随着物联网技术的迅猛发展&#xff0c;人们深刻认识到在智能化生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的物联网数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 钡铼…

从心理学角度看海外网红营销:品牌与消费者的心理互动

近年来&#xff0c;随着社交媒体的蓬勃发展&#xff0c;海外网红营销成为品牌推广的一种独特而有效的手段。这种新型营销方式不仅仅依赖于产品本身的特性&#xff0c;更加注重通过网红与消费者之间的心理互动来建立品牌形象&#xff0c;激发购买欲望。本文Nox聚星将和大家从心理…

17.用户身份与能力

Linux系统的管理员之所以是root&#xff0c;并不是因为它的名字叫root&#xff0c;而是因为该用户的身 份号码即UID&#xff08;User IDentification&#xff09;的数值为 0。在 Linux 系统中&#xff0c;UID就像我们的身份证号 码一样具有唯一性&#xff0c;因此可通过用户的U…

【明道云】学习笔记1-了解APaaS

【背景】 APaaS (Application Platform As A Service) &#xff0c;即应用程序平台即服务&#xff0c;这是基于PaaS&#xff08;平台即服务&#xff09;的一种解决方案&#xff0c;支持应用程序在云端的开发、部署和运行&#xff0c;提供软件开发中的基础工具给用户&#xff0…

基于XG24-EK2703A的BLE HID蓝牙键盘+鼠标复合设备功能开发(BLE+HID+FreeRTOS+Gecko SDK)

目录 项目介绍硬件介绍项目设计开发环境及工程参考总体流程图硬件基本配置应用初始化按键中断回调定时器回调按键响应任务蓝牙事件回调BLE HIDReport Map及报文键盘设备鼠标设备复合设备 发送字符串上/下滚动 功能展示项目总结 &#x1f449; 【Funpack3-1】基于XG24-EK2703A的…