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

【数据结构】24王道考研笔记——线性表

线性表

目录

  • 线性表
    • 定义和基本操作
    • 顺序表
      • 静态顺序表
      • 动态顺序表
    • 链表
      • 单链表
        • 不带头结点:
        • 带头结点:
      • 双链表
      • 循环链表
        • 循环单链表:
        • 循环双链表:
      • 静态链表
    • 顺序表链表比较
      • 逻辑结构:
      • 存储结构:
      • 基本操作:

定义和基本操作

线性表的定义:线性表时具有相同数据类型的n(n>=0)个数据元素有限序列,其中n为表长,当n=0时线性表是一个空表

L=(a1,a2,a3…,an) a1为表头元素,an为表尾元素,除第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素,每个元素有且仅有一个直接后继。

特点:

  1. 元素个数有限
  2. 元素具有逻辑上的顺序性,表中元素有其先后次序
  3. 元素都是数据元素,每个元素都是单个元素
  4. 元素数据类型相同,占有相同大小的存储空间
  5. 元素具有抽象性

线性表是一种逻辑结构,表示元素之间一对一的相邻关系,顺序表和链表是指存储结构。

线性表基本操作:

image.png

总结:

image.png

顺序表

线性表的顺序存储称为顺序表,使用一组地址连续的存储单元依次存储线性表中的数据元素,从而使得逻辑上相邻的两个元素在物理位置上也相邻。i为ai在线性表中的位序,元素的逻辑顺序与其物理顺序相同

image.png

线性表的顺序存储结构是一种随机存储的存储结构。

顺序表的特点:

  1. 随机访问,可以在O(1)时间内找到第i个元素 data[i-1]
  2. 存储密度高,每个结点智存初数据元素
  3. 拓展容量不方便(即使采用动态分配,拓展长度时间复杂度仍较高)
  4. 插入、删除操作不方便,需要移动大量元素

静态顺序表

一维数组可以静态分配也可以动态分配,静态分配时,数组大小和空间事先固定,不可变。而动态顺序表则不需要为线性表一次性划分所有空间。

结构体:

#define MaxSize 50typedef struct {int data[MaxSize];int length;
} SqList;

初始化:

//初始化
void InitList(SqList& L) {for (int i = 0; i < MaxSize; i++) {L.data[i] = 0;//将所有元素的初始值默认设置为0//这一步其实可以省略,但是省略之后,有可能受到内存中"脏数据"的影响}L.length = 0;
}

判空:

//判断是否为空
bool Empty(SqList L) {return (L.length == 0);
}

插入:

//插入
bool ListInsert(SqList& L, int i, int e) {//判断插入的位置是否合法,if (i < 1 || i > L.length + 1)return false;//判断表是否存满了if (L.length >= MaxSize)return false;//后面的元素后移for (int j = L.length; j >= i; j--) {L.data[j] = L.data[j - 1];}L.data[i - 1] = e;L.length++;return true;
}

删除:

//删除
bool ListDelete(SqList& L, int i, int& e) {//判断i的位置是否合法if (i < 0 || i > L.length) {return false;}//取出将要被删除的数e = L.data[i - 1];//将其后的数据前移for (int j = i; j <= L.length; j++) {L.data[j - 1] = L.data[j];}//线性表长度减一L.length--;return true;
}

查找:

//查找
//按位查找
int GetElem(SqList L, int i) {//判断是否越界if (i < 0 || i > L.length)return -1;return L.data[i - 1];
}
//按值查找
int LocateElem(SqList L, int e) {//循环出查找for (int i = 0; i < L.length; i++) {if (L.data[i] == e)return i + 1; //返回位序}return -1;
}

改值:

//先查找后改值
//由此分为两种方式,先按位查找后改值;或先按值查找后改值
//先按值查找后改值
bool LocateChangeElem(SqList& L, int e, int em) {//按值查找得到位序int bitOrder = LocateElem(L, e);//改值if (bitOrder != -1) {L.data[bitOrder] = em;return true;}else {return false;}
}//先按位序查找后改值
bool getChangeElem(SqList& L, int i, int em) {//给的位序,首先判断i是否合法if (i < 0 || i >= L.length)return false;//由于是用数组实现的方式,可以直接利用i查找L.data[i] = em;return true;}

打印:

//打印整个顺序表
void PrintSqList(SqList L) {//循环打印printf("开始打印顺序表\n");for (int i = 0; i < L.length; i++) {printf("Data[%d]==%d\n", i, L.data[i]);}printf("打印结束!\n");
}

动态顺序表

一旦数据空间占满,就另外开辟一块更大的存储空间,用以替换原来的存储空间,从而达到扩充存储空间的目的。

结构体:

#define InitSize 100
typedef struct {int* data; //指示动态分配数组的指针int MaxSize;//顺序表的最大容量int length;//顺序表当前的长度
} SeqList;

初始化:

//初始化
bool InitList(SeqList& L) {//用 malloc 函数申请一片连续的存储空间L.data = (int*)malloc(InitSize * sizeof(int));if (L.data == NULL)return false;//(int *) 是指针的强制类型转换L.length = 0;L.MaxSize = InitSize;return true;
}

判空:

//判空
bool Empty(SeqList L) {return (L.length == 0);
}

判满:

//判满
bool Full(SeqList L) {return (L.length >= L.MaxSize);
}

扩展空间:

//扩展空间
void IncreaseSize(SeqList& L, int len) {int* p = L.data;L.data = (int*)malloc((InitSize + len) * sizeof(int));for (int i = 0; i < L.length; i++) {L.data[i] = p[i];}L.MaxSize = L.MaxSize + len;free(p);//malloc 函数用于申请内存空间;free 函数用于释放内存空间;
}

插入:

//插入
bool ListInsert(SeqList& L, int i, int e) {//判断插入的位置是否合法,if (i < 1 || i > L.length + 1)return false;//判断表是否存满了
//    if (L.length>=L.MaxSize)
//        return fals;if (Full(L))return false;//后面的元素后移for (int j = L.length; j >= i; j--) {L.data[j] = L.data[j - 1];}L.data[i - 1] = e;L.length++;return true;
}

按位查找:

//按位查找
int GetElem(SeqList L, int i) {//判断是否越界if (i < 0 || i > L.length)return -1;return L.data[i - 1];
}

按值查找:

//按值查找
int LocateElem(SeqList L, int e) {//循环出查找for (int i = 0; i < L.length; i++) {if (L.data[i] == e)return i + 1; //返回位序}return -1;
}

删除:

//删除
bool ListDelete(SeqList& L, int i, int& e) {//判断i的位置是否合法if (i < 0 || i > L.length) {return false;}//取出将要被删除的数e = L.data[i - 1];//将其后的数据前移for (int j = i; j <= L.length; j++) {L.data[j - 1] = L.data[j];}//线性表长度减一L.length--;return true;
}

销毁:

//销毁
//由于动态分配方式使用malloc申请的内存空间,故需要使用free函数手动释放空间!
void DestroySqList(SeqList& L) {free(L.data);L.data = NULL;L.length = 0;
}

打印:

//打印整个顺序表
void PrintSqList(SeqList L) {if (L.data == NULL || L.length == 0)printf("这是一个空表!");else {//循环打印printf("开始打印顺序表\n");for (int i = 0; i < L.length; i++) {printf("Data[%d]==%d\n", i, L.data[i]);}printf("打印结束!\n");}
}

总结:

image.png

链表

单链表

线性表的链式存储称为单链表,它指通过一组任意的存储单元来存储线性表中的数据元素。每个链表结点存放元素自身的信息外,还需要存放一个指向其后继的指针。

image.png

结构体:

//结构体
typedef struct LNode {int data;struct LNode* next;
} LNode, * LinkList;
//等价于
//struct LNode{
//    int data;
//    struct LNode *next;
//};
//
//typedef struct LNode LNode;
//typedef struct LNode *LinkList;

LinkList强调为单链表 LNode*强调为结点,两者等价

不带头结点:

初始化:

//初始化
bool InitList(LinkList& L) {L = NULL;//空表暂时没有任何数据return true;
}

判空:

//判断是否为空
bool Empty(LinkList L) {return (L == NULL);
}
//等价于
//bool Empty1(LinkList L){
//    if (L==NULL)
//        return true;
//    else
//        return false;
//}

插入:

//在指定位置插入元素
bool ListInsert(LinkList& L, int i, int e) {if (i < 1)return false;//判断位序i是否合法//不带头节点时,插入位置正好为表头时,得单独处理if (i = 1) {LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = L;L = s;return true;}LNode* p;//指针指向当前扫面到的节点int j = 0;//记录p指向的节点的位序p = L;//L指向头节点,从头开始while (p != NULL && j < i - 1) {//循环扫描p = p->next;j++;}if (p == NULL) //i值超过来表长,不合法return false;LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;//下面的顺序不可交换s->next = p->next;p->next = s;return true;
}

带头结点:

初始化:

//初试化(带有头节点)
bool InitList(LinkList& L) {L = (LNode*)malloc(sizeof(LNode));//分配一个头节点if (L == NULL)return false;//头节点分配失败,可能是内存不足L->next = NULL;//头节点之后暂时没有节点,头节点也不存放数据return true;
}

判空:

//判空
bool Empty(LinkList L) {return (L->next == NULL);
}

打印链表:

void PrintList(LinkList L) {//循环打印整个链表LNode* p = L->next;//扫描指针int j = 0;if (p == NULL)printf("这是一个空表\n");while (p != NULL) {printf("LinkList[%d]=%d\n", j, p->data);p = p->next;j++;}
}

按位插入:

image.png

//按位插入
bool ListInsert(LinkList& L, int i, int e) {if (i < 1)return false;//判断位序i是否合法LNode* p;//指针指向当前扫面到的节点int j = 0;//记录p指向的节点的位序p = L;//L指向头节点,从头开始while (p != NULL && j < i - 1) {//循环扫描p = p->next;j++;}if (p == NULL) //i值超过来表长,不合法return false;LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;//下面的顺序不可交换s->next = p->next;p->next = s; //将结点s连到p之后return true;
}

后插操作:(包含于之前的插入操作之中)

//指定节点的后插操作
bool InsertNextNode(LNode* p, int e) {if (p == NULL)return false;//判断指定节点是否存在LNode* s = (LNode*)malloc(sizeof(LNode));if (s == NULL)return false;//分配内存失败s->data = e;s->next = p->next;p->next = s;return true;
}

前插操作:由于难以获得前一个链表元素信息,所以先完成后插,再交换两者数据实现前插

//指定节点的前插操作
//先完成后插,再交换数据以实现前插
bool InsertPriorNode(LNode* p, int e) {if (p == NULL)return false;LNode* s = (LNode*)malloc(sizeof(LNode));if (s == NULL)return false;s->next = p->next;p->next = s;s->data = p->data;p->data = e;return true;
}

按指定位序删除并返回值:

//按指定位序删除节点并返回其值
bool ListDelete(LinkList& L, int i, int& e) {if (i < 1)return false;LNode* p;int j = 0;p = L;while (p != NULL && j < i - 1) {p = p->next;j++;}LNode* q = p->next;e = q->data;p->next = q->next;free(q);return true;
}

删除指定节点:若p为最后一个元素,则存在问题,只能通过从头结点开始顺序找到其前序节点的方法来进行删除。

image.png

//删除指定节点
bool DeleteNode(LNode* p) {if (p == NULL){return false;}LNode* q = p->next;//令q指向*p的后续结点p->data = p->next->data;//和后续结点交换数据域p->next = q->next;//将*q结点从链中“断开”free(q);//释放后续结点的存储空间return true;
}

按值查找:

//按值查找
LNode* LocateElem(LinkList L, int e)
{LNode* p = L->next;//从第1个结点开始查找数据域为e的结点while (p != NULL && p->data != e){p = p->next;}return p;//找到后返回该结点指针,否则返回NULL;
}

按位查找:

//按位查找
LNode* GetElem(LinkList L, int i)
{if (i < 0){return NULL;}LNode* p;//指针p指向当前扫描到的结点int j = 0;//当前p指向的是第几个结点p = L;//L指向头结点,头结点是第0个结点(不存数据)while (p != NULL && j < i){p = p->next;j++;}return p;
}

求表长:

//求表长
int Lnegth(LinkList L)
{int len = 0;//统计表长LNode* p = L;while (p->next != NULL){p = p->next;len++;}return len;
}

尾插法建表:设置一个表尾指针,方便直接在队尾进行尾插操作

//尾插法建立单链表(正向建立单链表)
LinkList List_TailInsert(LinkList& L)
{int x;L = (LinkList)malloc(sizeof(LNode));//建立头结点LNode* s, * r = L;//r为表尾指针,方便尾插scanf("%d", &x);//输入结点的值while (x != 9999)//输入9999表示结束{s = (LNode*)malloc(sizeof(LNode));s->data = x;r->next = s;r = s;//r指向新的表尾结点,永远保持r指向最后一个结点,避免重复操作scanf("%d", &x);}r->next = NULL;return L;
}

头插法建立单链表(不断对头结点进行尾插操作)

//头插法建立单链表(不断对头结点进行尾插操作)
LinkList List_HeadInsert(LinkList& L)//逆向建立单链表
{LNode* s;int x;L = (LinkList)malloc(sizeof(LNode));//创建头结点L->next = NULL;//初始为空链表scanf("%d", &x);//输入结点的值while (x != 9999)//输入9999表示结束{s = (LNode*)malloc(sizeof(LNode));//创建新结点s->data = x;s->next = L->next;L->next = s;//将新结点插入表中,L为头指针scanf("%d", &x);}return L;
}

双链表

在单链表的基础上加入prior前驱指针,使得插入、删除操作的时间复杂度变为O(1)(可以很方便地找到前驱)

image.png

结构体:

typedef struct DNode {int data;//数据域struct DNode* prior, * next;//前指针和后指针
} DNode, * DLinkList;

初始化:

//初始化
bool InitDLinkList(DLinkList& L) {L = (DNode*)malloc(sizeof(DNode));//分配一个头节点if (L == NULL)return false;L->prior == NULL;//头节点前后指针都指向空L->next == NULL;return true;
}

判空:

//判空
bool Empty(DLinkList L) {return (L->next == NULL);
}

后插:

//指定节点的后插操作
bool InsertNextElem(DNode* p, DNode* s) {s->next = p->next;if (p->next != NULL){p->next->prior = s;//防止出现p后面没有后继结点的情况}s->prior = p;p->next = s;
}

删除p后继结点:

//删除P节点的后继节点
bool DeleteNextNode(DNode* p) {if (p == NULL)return false;//p节点为空DNode* q = p->next;if (q == NULL)return false;//P节点没有后继p->next = q->next;if (q->next != NULL)//q不是最后一个节点q->next->prior = p;free(q);//手动释放内存空间return true;
}

销毁整个表:

//销毁整个表
bool DestroyList(DLinkList& L) {//循环删除并释放每个节点while (L->next != NULL)DeleteNextNode(L);free(L);//释放头节点L = NULL;//头指针指向NULL
}

循环链表

循环链表的最后一个指针不是NULL而是改为指向头结点。

循环单链表:

结构体:

typedef struct LNode {int data;struct LNode* next;
}LNode, * LinkList;

初始化:

//初始化一个循环单链表
bool InitRLinkList(LinkList& L) {L = (LNode*)malloc(sizeof(LNode));//分配一个头节点if (L == NULL)return false;//内存不足,分配失败;L->next = L;//头节点nex指向头节点,以此形成循环链表return true;
}

判空:

bool Empty(LinkList L)
{if (L->next == L)return true;elsereturn false;
}

判尾:

//判断P是不是表尾指针
bool IsTail(LinkList L, LNode* p) {return (p->next == L);
}

循环双链表:

结构体:

typedef struct DNode {int data;struct DNode* prior, * next;
}DNode, * DLinkList;

初始化:

//初始化
bool InitRDLinkList(DLinkList& L) {L = (DNode*)malloc(sizeof(DNode));//分配头节点if (L == NULL)return false;L->prior = L;L->next = L;//循环抱住自己return true;
}

判尾:

//判断节点p是不是循环双链表的表尾节点
bool iTail(DLinkList L, DNode* p) {return (p->next == L);
}

插入:

//在p节点之后插入s节点
bool InsertNextDNode(DNode* p, DNode* s) {s->next = p->next;p->next->prior = s;s->prior = p;p->next = s;return true;
}

删除:

//删除操作
bool DeleteNextDNode(DLinkList& L, DNode* p) {DNode* q = p->next;p->next = q->next;q->next->prior = p;free(q);return true;
}

静态链表

静态链表借助数组来描述线性表的线性存储结构,这里的指针next记录的是结点的相对地址(数组下标),又称游标,和顺序表一样,静态链表也要预先分配一块连续的内存空间。

image.png

静态链表以next==-1作为结束标志,插入、删除操作与动态链表的相同,只需要修改指针,而不需要移动元素。

结构体:

//第一种定义方法
struct Node0 {int data;//存储数据元素int next;//下一个元素的数组下标
};
typedef struct Node SLinkList[MaxSize];//第二种定义方法
typedef struct Node {int data;int next;
}SLinkList[MaxSize];

优点:增删操作不需要大量移动元素

缺点:不能随机存取,只能从头结点开始一次往后查找:容量固定不可变

顺序表链表比较

逻辑结构:

都属于线性表,都是线性结构。

采用顺序存储时,逻辑上相邻的元素,物理存储位置也相邻,采用链式存储时,逻辑上相邻的元素,物理存储位置不一定相邻,逻辑关系通过指针链接表示。

存储结构:

image.png

基本操作:

image.png

image.png

image.png

image.png

总结:

image.png
主要参考:王道考研课程
后续会持续更新考研408部分的学习笔记,欢迎关注。
github仓库(含所有相关源码):408数据结构笔记

相关文章:

【数据结构】24王道考研笔记——线性表

线性表 目录 线性表定义和基本操作顺序表静态顺序表动态顺序表 链表单链表不带头结点&#xff1a;带头结点&#xff1a; 双链表循环链表循环单链表&#xff1a;循环双链表&#xff1a; 静态链表 顺序表链表比较逻辑结构&#xff1a;存储结构&#xff1a;基本操作&#xff1a; 定…...

【Linux C】基于树莓派/香橙派的蓝牙服务端——支持多蓝牙设备接入

一、需求 在树莓派/香橙派上利用开发板自带的蓝牙作为一个蓝牙服务端&#xff08;主机&#xff09;&#xff0c;允许外来设备&#xff08;从机&#xff09;通过蓝牙接入进行通信&#xff0c;通信格式为透传方式&#xff1b;采用的编程语言为Linux C 二、环境准备 bluez安装 …...

鸿蒙App开发选择Java还是JavaScript?

众所周知&#xff0c; Java和 JavaScript是两种编程语言&#xff0c;这两种语言在不同的环境中都有许多用途。在鸿蒙 App开发中&#xff0c; Java和 JavaScript是两种常见的编程语言&#xff0c;它们都具有广泛的应用&#xff0c;并且都有其独特的优势。下面我们将就这两种编程…...

【Android】CountDownTimer的使用

android中怎么实现倒计时 在Android中&#xff0c;可以使用CountDownTimer类来实现倒计时。以下是一个简单的示例&#xff1a; javaCopy new CountDownTimer(30000, 1000) {public void onTick(long millisUntilFinished) {// 每次倒计时间隔1秒&#xff0c;更新UI上的倒计时剩…...

Linux :: 【基础指令篇 :: 文件及目录操作:(1)】:: ls :: 查看指定目录下的内容

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 目录索引&am…...

【商品详情 +关键词搜索】API 接口系列

首先&#xff0c;大家要到官方主页去申请一个 appkey&#xff0c;这个是做什么用的呢&#xff1f;App Key 是应用的唯一标识&#xff0c;TOP 通过 App Key 来鉴别应用的身份。AppSecret 是 TOP 给应用分配的密钥&#xff0c;开发者需要妥善保存这个密钥&#xff0c;这个密钥用来…...

RabbitMQ学习-发布确认高级

发布确认springboot版本 确认机制方案&#xff1a; 代码架构图&#xff1a; 配置文件&#xff1a; 在application.properties全局配置文件中添加spring.rabbitmq.publish-confirm-type属性&#xff0c;这个属性有以下几种值 none:禁用发布确认模式(默认)0 correlated:发布消…...

重载和内联函数

函数的默认参数 默认参数是指调用函数的时候&#xff0c;如果不写实参&#xff0c;那么将使用一个缺省值。 使用默认参数可以使你的函数更加灵活&#xff0c;同时减少了在不同上下文中为相同的参数重复编写相同的代码的需要。 return_type function_name(data_type paramete…...

从零学算法

198.你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个房屋存放金额…...

《Linux0.11源码解读》理解(四) head之重新设置IDT/GDT

上节提到&#xff0c;现在cs:ip指向0地址&#xff0c;此处存储着作为操作系统核心代码的system模块&#xff0c;是由head.s和 main.c以及后面所有源代码文件编译链接而成。head.s(以下简称head)紧挨着main.c&#xff0c;我们先执行head。 重新设置内核栈 _pg_dir: _startup_3…...

<SQL>《SQL命令(含例句)精心整理版(4)》

《SQL命令&#xff08;含例句&#xff09;精心整理版&#xff08;4&#xff09;》 14 数据库对象14.1 表14.2 视图14.3 存储过程14.3.1 概念14.3.2 创建存储过程14.3.2 调用存储过程14.3.3 DbVisualizer工具中调用方法14.3.3 DB2命令行脚本调用方法14.3.4 DB2中两个存储过程报错…...

C++死锁

死锁是指两个或两个以上的线程在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象&#xff0c;若无外力作用&#xff0c;它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁&#xff0c;这些永远在互相等待的状态称为死锁。 死锁通常发生…...

[自学记录02|百人计划]纹理压缩

一、什么是纹理压缩 纹理压缩是为了解决内存、带宽问题&#xff0c;专为在计算机图形渲染系统中存储纹理而使用的图像压缩技术。 1.图片格式和纹理格式的区别 (1)图片格式 图片格式是图片文件的存储格式&#xff0c;通常在磁盘、内存中储存和传输文件时使用&#xff1b;例如…...

C++泛型编程之模板

目录 一、什么是泛型编程 二、函数模板 2.1函数模板的概念 2.2函数模板格式 2.3函数模板的原理 2.5函数模板的实例化 2.6模板参数的匹配原则 三、类模板 3.1类模板的定义格式 3.2 类模板的实例化 四、非类型模板参数 五、模板的特化 5.1模板特化的概念&#xff1a;…...

极氪汽车 APP 系统云原生架构转型实践

作者&#xff1a;极氪汽车 前言 新能源汽车已经成为我国汽车市场再次崛起的关键支柱&#xff0c;随着新能源汽车市场的快速发展&#xff0c;不同类型的品牌造车厂商呈现出百花齐放的态势。极氪汽车是吉利控股集团旗下高端纯电汽车新品牌&#xff0c;2021 年 4 月极氪发布首款…...

一个UDP下载服务器的实现(模拟下载文件)

本期分享的主要是使用UDP实现文件下载功能&#xff0c;需要自己编写服务器和客户端&#xff0c;实现的功能主要有以下几个&#xff1a; &#xff08;1&#xff09;服务器可以为请求的用户下发文件数据&#xff08;前提是服务器得有这个数据文件&#xff09; &#xff08;2&…...

01.hadoop上课笔记之hadoop介绍

1.大数据介绍 可以对未来数据预测 google通过搜索预测流感,足球球员有一 定关联…caict可以得到数据hbase hive林子雨mooc数据要进行挖掘(推断更多信息) 2.大数据是非结构化数据多:声音,图片… 3.大数据影响因素 大多快低 tb pb eb zb 1.硬件 2.网络带宽 4.大数据的特征 数据量…...

小鹏汽车Q1财报:押注G6、大力降本,明年智驾BOM降半

‍作者 | 德新编辑 | 王博 小鹏汽车本周发了Q1财报&#xff0c;数据不好看&#xff0c;以致于在微博端也发了公开信。 那后续呢&#xff1f; 小鹏第二季度指引是&#xff0c;总交付数量约为2.1 - 2.2万辆&#xff0c;收入预计约为45 - 47亿元&#xff1b;四季度&#xff0c…...

VMware ESXi 8.0U1a 发布 - 领先的裸机 Hypervisor

VMware ESXi 8.0U1a 发布 - 领先的裸机 Hypervisor 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-8-u1/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023-06-01, VMware vSphere 8.0U1a 发布。 详见&am…...

Unity的IPreprocessBuild:深入解析与实用案例

Unity IPreprocessBuild Unity IPreprocessBuild是Unity引擎中的一个非常有用的功能&#xff0c;它可以让开发者在构建项目时自动执行一些操作。这个功能可以帮助开发者提高工作效率&#xff0c;减少手动操作的时间和错误率。在本文中我们将介绍Unity IPreprocessBuild的使用方…...

htmlCSS-----CSS选择器(下)

目录 前言&#xff1a; 2.高级选择器 &#xff08;1&#xff09;子代选择器 &#xff08;2&#xff09;伪类选择器 &#xff08;3&#xff09;后代选择器 &#xff08;4&#xff09;兄弟选择器 相邻兄弟选择器 通用兄弟选择器 &#xff08;5&#xff09;并集选择器 &am…...

RDK X3 Module发布,全新软硬件平台加速实现量产级产品落地

机器人开发是一段美妙的旅程。GEEKROS创始人杨状状是地平线社区的一名开发者&#xff0c;热衷于鼓捣各类机器人&#xff0c;2022年&#xff0c;状状第一时间就拿到了地平线旭日X3派&#xff08;简称旭日X3派&#xff09;&#xff0c;基于TogetheROS™.Bot机器人操作系统&#x…...

【面试实战】Redis缓存设计

文章目录 Redis缓存出现的问题🙎‍♂️面试官:什么是缓存雪崩?🙎‍♂️面试官:怎样解决缓存雪崩?🙎‍♂️面试官:什么是缓存击穿?🙎‍♂️面试官:怎样解决缓存击穿?🙎‍♂️面试官:什么是缓存穿透?🙎‍♂️面试官:怎样解决缓存穿透?🙎‍♂️面试官:…...

如何解决js定时器不准确问题

为什么会出现定时器不准确呢&#xff1f; 这个其实就得提到js执行机制了&#xff0c;叫做事件循环Eventloop 循环机制中&#xff0c;异步事件 setInterval 到时后会把回调函数放入消息队列中Event Queue&#xff0c;主线程的宏任务执行完毕后依次执行消息队列的微任务&#xff…...

学习笔记——vue中使用el-dropdown组件报错

今天在工作中&#xff0c;发现使用el-select做的下拉框&#xff0c;下拉菜单展开后&#xff0c;鼠标点击下拉框之外的区域时&#xff0c;下拉菜单没有收起。然后&#xff0c;我打开控制台&#xff0c;发现了这个错误。 Uncaught TypeError: Cannot read properties of null (re…...

Java之旅(八)

Java 条件运算符 Java 条件运算符用于根据一个条件表达式的布尔值来决定程序执行的流程。条件运算符有三种类型&#xff1a;if、else 和 switch。 if 语句的一般格式如下&#xff1a; if (condition) {// 条件为 true 执行的代码块 } 其中&#xff0c;condition 是一个 bool…...

华为OD机试真题(Java),四则运算(100%通过+复盘思路)

一、题目描述 输入一个表达式(用字符串表示),求这个表达式的值。 保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。 数据范围:表达式计算结果和过程中满足∣val∣≤1000 ,字符串长度满…...

HTML表单标签form分析

说明&#xff1a;在html的标签中&#xff0c;表单标签与后台联系密切&#xff0c;像用户登录、注册&#xff0c;都是用到页面的表单标签&#xff0c;用户将信息填入到表单中&#xff0c;提交到后端业务中校验处理&#xff0c;再将结果反馈给前端页面。 表单内的标签分别有&…...

Qt 项目文件Pri详解

在Qt项目中&#xff0c;pri文件(.pri)是一种类似于makefile的文件&#xff0c;用于定义Qt项目中的编译规则。通常可以用pri文件来配置Qt库、头文件、源文件、链接库等信息&#xff0c;这样可以把这些信息定义在一个文件中&#xff0c;避免在每个工程中都进行重复配置&#xff0…...

Keil 5 MDK 发律师函警告了,如何用STCubeIDE开发标准库的程序(STM32F103C8T6为例)

用STCubeIDE进行标准库开发 1、CubeIDE介绍 https://www.stmcu.com.cn/ecosystem/Cube/STM32CubeIDE 2、CubeIDE下载 点击上面的链接&#xff0c;登录即可下载 3、搭建Demo工程 新建一个工作空间 创建一个工程 选择芯片-STM32F103C8T6 填写工程信息 添加标准库到工程 标…...