【数据结构】线性表,顺序表
一. 线性表
1. 线性表(linear list)是n个具有相同特性的数据元素的有限序列。
2. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...
3. 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
二. 顺序表
1. 静态顺序表与动态顺序表
1. 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。
2. 顺序表一般可以分为:
静态顺序表:使用定长数组存储元素。
#define N 10 typedef int SLDataType; typedef struct SeqList {SLDataType array[N]; //定长数组size_t size; //有效数据个数 }SeqList;
动态顺序表:使用动态开辟的数组存储。
typedef int SLDataType; typedef struct SeqList {SLDataType* array; //指向动态开辟的数组size_t size; //有效数据个数size_t capacity; //空间容量 }SeqList;
2. 动态顺序表的接口实现
1. 静态顺序表只适用于确定知道需要存多少数据的场景。
2. 静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。
3. 所以现实中基本都是使用动态顺序表,根据需要动态的分配空间大小,所以下面我们实现动态顺序表。
2.1 顺序表初始化
1. 将结构的每个成员进行初始化
void SeqListInit(SeqList* psl, size_t capacity) {assert(psl);psl->array = (SLDataType*)malloc(sizeof(SeqList) * capacity);if (psl->array == NULL){perror("malloc");return;}psl->size = 0;psl->capacity = capacity; }
2.2 判断是否需要扩容
1. 判断有效个数是否和容量相等。
2. 使用realloc增容。
void CheckCapacity(SeqList* psl) {assert(psl);if (psl->size == psl->capacity){SLDataType* tmp = (SLDataType*)realloc(psl->array, sizeof(SLDataType) * psl->capacity * 2);if (tmp == NULL){perror(realloc);return;}psl->array = tmp;psl->capacity *= 2;} }
2.3 顺序表指定位置插入
1. 对pos进行范围判断。
1. 判断是否需要扩容。
2. 将pos后面的元素往后挪一位。
3. pos位置插入值。
4. 有效个数加一。
void SeqListInsert(SeqList* psl, size_t pos, SLDataType x) {assert(psl);assert(pos >= 0 && pos <= psl->size);CheckCapacity(psl);size_t cur = psl->size;while (cur != pos){psl->array[cur] = psl->array[cur - 1];cur--;}psl->array[pos] = x;psl->size++; }
2.4 顺序表头插
1. 判断是否需要扩容。
2. 将所有元素都往后移一位,留出第一个位置插入(如果头插之前没有元素,则直接插入即可)。
3. 有效个数加一。
void SeqListPushFront(SeqList* psl, SLDataType x) {assert(psl);CheckCapacity(psl);int tmp = psl->size;while (tmp > 0) //当本身为空时,就不走这个循环{psl->array[tmp] = psl->array[tmp - 1];tmp--;}psl->array[0] = x;psl->size++; }
方法2:复用SeqListInsert
void SeqListPushFront(SeqList* psl, SLDataType x) {SeqListInsert(psl, 0, x); }
2.5 顺序表尾插
1. 插入前判断是否需要增容。
2. size作为下标正好是最后一个元素的后一位。
void SeqListPushBack(SeqList* psl, SLDataType x) {assert(psl);CheckCapacity(psl);psl->array[psl->size++] = x; }
方法2:复用SeqListInsert
void SeqListPushBack(SeqList* psl, SLDataType x) {assert(psl);SeqListInsert(psl, psl->size, x); }
2.6 顺序表指定位置删除
1. 判断pos是否合法。
2. 将pos后面的元素往前覆盖一位。
3. 有效个数减一。
void SeqListErase(SeqList* psl, size_t pos) {assert(psl);assert(pos >= 0 && pos < psl->size);int cur = pos;while (cur < psl->size - 1){psl->array[cur] = psl->array[cur + 1];cur++;}psl->size--; }
2.7 顺序表头删
1. 判断有效个数是否为0,为0不用删。
2. 将后面的与元素往前覆盖一位。
3. 有效元素个数减一。
void SeqListPopFront(SeqList* psl) {assert(psl);assert(psl->size);size_t cur = 0;while (cur < psl->size - 1){psl->array[cur] = psl->array[cur + 1];cur++;}psl->size--; }
方法2:复用SeqListErase
void SeqListPopFront(SeqList* psl) {assert(psl);SeqListErase(psl, 0); }
2.8 顺序表尾删
1. 判断size,size如果为0就不能删。
2. 删除尾部元素直接将size减减即可。
void SeqListPopBack(SeqList* psl) {assert(psl);assert(psl->size);psl->size--; }
方法2:复用SeqListErase
void SeqListPopBack(SeqList* psl) {assert(psl);SeqListErase(psl, psl->size - 1); }
2.9 顺序表查找
1. 遍历一遍进行比较。
2. 找到返回下标,否则返回-1。
int SeqListFind(SeqList* psl, SLDataType x) {assert(psl);for (size_t i = 0; i < psl->size; i++){if (psl->array[i] == x) return i;}return -1; }
2.10 顺序表修改
1. 对pos进行范围判断。
2. 将pos作为下标进行修改。
void SeqListModify(SeqList* psl, size_t pos, SLDataType x) {assert(psl);assert(pos >= 0 && pos < psl->size);psl->array[pos] = x; }
2.11 顺序表销毁
1. 销毁时需要释放空间,指针置空。
2. 有效个数和容量置0。
void SeqListDestory(SeqList* psl) {assert(psl);free(psl->array);psl->array = NULL;psl->capacity = 0;psl->size = 0; }
2.12 顺序表打印
1. 遍历数组打印
void SeqListPrint(SeqList* psl) {assert(psl);for (int i = 0; i < psl->size; i++) printf("%d ", psl->array[i]);printf("\n"); }
3. 顺序表的缺点
1. 中间/头部的插入删除,时间复杂度为O(N)。
2. 增容需要申请新空间,拷贝数据,释放旧空间,会有不小的消耗。
3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。
4. 顺序表编程练习题
4.1 移除元素
链接:. - 力扣(LeetCode)
思路:
1. src遍历判断,等于val就什么也不做,不等于val就把当前值给dst。
2. 等待src给我值,然后加加。
int removeElement(int* nums, int numsSize, int val) {int dst = 0;for(int src=0; src<numsSize; src++){if(nums[src] != val) nums[dst++] = nums[src];}return dst; }
4.2 删除有序数组中的重复项
链接:. - 力扣(LeetCode)
思路:利用双指针进行比较。
int removeDuplicates(int* nums, int numsSize) {int dst = 0;for(int src=1; src<numsSize; src++){if(nums[dst] != nums[src]) nums[++dst] = nums[src];}return dst+1; }
4.3 合并两个有序数组
链接:. - 力扣(LeetCode)
思路:
1. 从后面开始比较,谁大谁放在后面。
2. 注意结束条件,这里以tail为标准。
void merge(int* nums1, int nums1Size, int m, int* nums2, int nums2Size, int n) {int src1 = m-1;int src2 = n-1;int tail = nums1Size-1;while(tail>=0){if(src2<0) break;if(src1<0) nums1[tail] = nums2[src2--];else if(nums2[src2] >= nums1[src1]) nums1[tail] = nums2[src2--];else if(nums2[src2] < nums1[src1]) nums1[tail] = nums1[src1--];tail--;} }
三. 链表
1. 链表的概念及结构
概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。
2. 单链表实现
2.1 单链表节点结构
1. 使用typedef重命名数据类型是为了方便类型的更改。
2. 结构包含存放的数据和指向下一个节点的地址。
typedef int SLDataType; typedef struct SingleListNode {SLDataType data;struct SingleListNode* next; }SLNode;
2.2 动态申请一个节点
1. 使用malloc申请一块节点空间。
2. 将节点内容初始化。
SLNode* BuySLNode(SLDataType x) {SLNode* newnode = (SLNode*)malloc(sizeof(SLNode));if (newnode == NULL){perror("malloc");return NULL;}newnode->data = x;newnode->next = NULL;return newnode; }
2.3 单链表打印
1. 通过获取下一个节点地址进行遍历并打印数据。
2. 遇到空节点停下。
void SLPrint(SLNode* plist) {SLNode* cur = plist;while (cur){printf("%d->", cur->data);cur = cur->next;}printf("NULL\n"); }
2.4 单链表尾插
1. pplist不可能为空,所以加断言。
2. 无节点情况:直接将新节点地址给头指针。
3. 有节点情况:将最后一个节点连接新节点。
void SLPushBack(SLNode** pplist, SLDataType x) {assert(pplist);SLNode* newnode = BuySLNode(x);if (*pplist == NULL) *pplist = newnode; //无节点else //有节点{SLNode* cur = *pplist;while (cur->next != NULL) cur = cur->next;cur->next = newnode;} }
2.5 单链表头插
1. 先将新节点连接第一个结点,再将头指针连接新节点。
void SLPushFront(SLNode** pplist, SLDataType x) {assert(pplist);SLNode* newnode = BuySLNode(x);newnode->next = *pplist;*pplist = newnode; }
2.6 单链表尾删
1. 单节点情况:释放节点然后置空。
2. 多节点情况:利用倒数第二个节点,释放倒数第一个节点并置空。
void SLPopBack(SLNode** pplist) {assert(pplist && *pplist);SLNode* cur = *pplist;if (cur->next == NULL) //单节点{free(cur);*pplist = NULL;}else //多节点{while (cur->next->next != NULL) cur = cur->next;free(cur->next);cur->next = NULL;} }
2.7 单链表头删
1. *pplist不能为空,因为空节点不用删。
2. 将头指针指向第二个节点,释放第一个节点。
void SLPopFront(SLNode** pplist) {assert(pplist && *pplist);SLNode* del = *pplist;*pplist = del->next;free(del); }
2.8 单链表查找
1. 遍历一遍,比较数据。
SLNode* SLFind(SLNode* plist, SLDataType x) {SLNode* cur = plist;while (cur){if (cur->data == x) return cur;cur = cur->next;}return NULL; }
2.9 单链表在pos后一位插入x
1. 先将新节点连接pos的后一个节点,再将pos连接新节点。
void SLInsertAfter(SLNode* pos, SLDataType x) {assert(pos);SLNode* newnode = BuySLNode(x);newnode->next = pos->next;pos->next = newnode; }
2.10 单链表删除pos后一位的值
1. 空节点不用删。
2. 将pos和pos后面第二个节点连接,释放pos后面第一个节点。
void SLEraseAfter(SLNode* pos) {assert(pos);SLNode* del = pos->next;pos->next = del->next;free(del); }
3. 链表的分类
4. 双向链表的实现
5. 链表编程练习题
5.1 移除链表元素
链接:. - 力扣(LeetCode)
思路:
1. 遍历链表,删除相同值得节点。
2. 使用前后指针,方便节点的释放。
3. 注意特殊情况,当第一个节点就需要删除的时候。
struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur = head;struct ListNode* prev = NULL;while(cur){if(cur->val == val){ if(prev == NULL) //这里判断的是当前是不是第一个节点,{ //注意,删除完第一个节点后,第二个节点会变成新的第一个节点。cur = cur->next;free(head);head = cur;}else{prev->next = cur->next;free(cur);cur = prev->next;}}else{prev = cur;cur = cur->next;}}return head; }
5.2 链表的中间结点
链接:. - 力扣(LeetCode)
思路:
1. 快慢指针,slow一次走一步,fast一次走两步。
2. 有奇数节点,偶数节点两种情况,奇数节点时fast走到最后一个节点停下,偶数节点时fast走到空停下。
struct ListNode* middleNode(struct ListNode* head) {struct ListNode* slow = head;struct ListNode* fast = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}return slow; }
5.3 合并两个有序链表
链接:. - 力扣(LeetCode)
思路:
1. 将小于或等于的节点尾插到一个新的指针上,返回这个指针。
2. 注意第一个节点尾插需要特殊处理。
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {if(list1 == NULL) return list2;if(list2 == NULL) return list1;struct ListNode* list3 = NULL;struct ListNode* cur = NULL;while(list1 && list2){if(list1->val <= list2->val){if(list3 == NULL) list3 = cur = list1;else{cur->next = list1;cur = cur->next;}list1 = list1->next;}else{if(list3 == NULL) list3 = cur = list2;else{cur->next = list2;cur = cur->next;}list2 = list2->next;}}if(list1) cur->next = list1;if(list2) cur->next = list2;return list3; }
5.4 反转链表
链接:. - 力扣(LeetCode)
思路1:用三个指针来实现反转。
struct ListNode* reverseList(struct ListNode* head) {if(head == NULL) return NULL;struct ListNode* n1 = NULL;struct ListNode* n2 = head;struct ListNode* n3 = head->next;while(n2){n2->next = n1;n1 = n2;n2 = n3;if(n3) n3 = n3->next;}return n1; }
思路2:头插法,每次cur节点对rhead进行头插。
struct ListNode* reverseList(struct ListNode* head) {struct ListNode* rhead = NULL;struct ListNode* cur = head;while(cur){struct ListNode* next = cur->next;cur->next = rhead;rhead = cur;cur = next;}return rhead; }
5.5 链表分割
链接:链表分割_牛客题霸_牛客网
思路:
1. 分两个链表,将小于x的尾插一个链表,大于等于x的尾插另一个链表,最后连接起来。
2. 建议用带哨兵位的链表。
3. 连接起来后第二个链表最后记得指向NULL。
ListNode* partition(ListNode* pHead, int x) {ListNode* h1 = (ListNode*)malloc(sizeof(ListNode));ListNode* h2 = (ListNode*)malloc(sizeof(ListNode));ListNode* h1tail = h1;ListNode* h2tail = h2;ListNode* cur = pHead;while(cur){if(cur->val < x){h1tail->next = cur;h1tail = h1tail->next;}else { h2tail->next = cur;h2tail = h2tail->next;}cur = cur->next;}h1tail->next = h2->next;h2tail->next = NULL;pHead = h1->next;free(h1);free(h2);return pHead;}
5.6 相交链表
链接:. - 力扣(LeetCode)
思路:
1. 先求两个链表的长度。
2. 长的链表头指针先走,走到和短的链表一样长。
3. 两个指针一起走,直到遇到一样的节点。
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {int lenA = 0;int lenB = 0;struct ListNode* cur = headA;while(cur){lenA++;cur = cur->next;}cur = headB;while(cur){lenB++;cur = cur->next;}int gap = abs(lenA-lenB);struct ListNode* longlist = headA;struct ListNode* shortlist = headB;if(lenA < lenB){longlist = headB; shortlist = headA; }while(gap--) longlist = longlist->next; while(longlist != shortlist){longlist = longlist->next;shortlist = shortlist->next;}return longlist; }
5.7 环形链表
链接:. - 力扣(LeetCode)
思路:
1. 利用快慢指针,如果有环那么会相遇,如果没环就走到链表结束。
bool hasCycle(struct ListNode *head) {struct ListNode *fast = head;struct ListNode *slow = head;while(fast && fast->next){slow = slow->next;fast = fast->next->next;if(slow == fast) return true;} return false; }
面试问题:
1. 快指针走两步,慢指针走一步,快指针和慢指针一定会相遇吗?
答:一定会,当他们进入环后,距离不断减1直到0。
快指针走n步,慢指针走一步,假设快指针追到慢指针的距离为N,那么N必须是n-1的倍数才有能追上。错过之后,N也会发生变化。
6. 顺序表和链表的区别
相关文章:

【数据结构】线性表,顺序表
一. 线性表 1. 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 2. 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串... 3. 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理…...

Spring之最基础的创建与Bean的存储与获取(还有Maven加载jar包报错的解决方法)
目录 创建Spring项目 如何解决Maven加载jar包报错 存储Bean和取Bean 在Java中对象也称为Bean。所以后面我提到Bean,大家要知道我说的是什么。 创建Spring项目 我的idea是2022版本的,如果大家和我一样可以参考我的。 1.创建一个Maven项目。图片上忘了…...

RabbitMQ应用问题 - 消息顺序性保证、消息积压问题
文章目录 MQ 消息顺序性保证概述原因分析解决方案基于 spring-cloud-stream 实现分区消费 消息挤压问题概述原因分析解决方案 MQ 消息顺序性保证 概述 a)消息顺序性:消费者消费的消息的顺序 和 生产者发送消息的顺序是一致的. 例如 生产者 发送消息顺序…...

linux tcp通讯demo
linux tcp通讯demo代码。通过用chatgpt生成的代码。做一个代码记录。 一、基本的通讯demo server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h>…...

在 MongoDB 中,如何配置副本集以实现读写分离?
在 MongoDB 中,配置副本集以实现读写分离主要涉及以下几个步骤: 初始化副本集: 创建副本集时,需要在所有参与节点上运行 rs.initiate() 命令。这将初始化一个新的副本集。 添加成员到副本集: 使用 rs.add() 命令将所有…...

虚拟dom-Diff算法
虚拟dom-Diff算法 vue2 diff算法在vue2中就是patch,通过新旧虚拟dom对比,找到最小变化然后进行dom操作 在页面首次渲染的时候会调用一次patch并创建新的vnode,不会进行深层次的比较,然后再组件中数据发生变化的时候,…...

01创建型设计模式——单例模式
一、单例模式简介 单例模式(Singleton Pattern)是一种创建型设计模式(GoF书中解释创建型设计模式:一种用来处理对象的创建过程的模式),单例模式是其中的一种,它确保一个类只有一个实例ÿ…...

图像分割(一)
一、概述 语义分割:是把每个像素都打上标签(这个像素点是人、树、背景等) 实例分割:不光要区别类别,还要区分类别中的每一个个体 损失函数:逐像素的交叉熵;样本均衡问题 MIOU指标:…...

C++ 新经典:设计模式 目录(先留框架,慢慢来~)
C 新经典:设计模式 C 新经典:设计模式 C 新经典:设计模式第1章 设计模式与软件开发思想、编程环境介绍第2章 模板方法模式第3章 工厂模式、原型模式、建造者模式第4章 策略模式第5章 观察者模式第6章 装饰模式第7章 单件模式第8章 外观模式第…...

go之命令行工具urfave-cli
一、urfave/cli urfave/cli 是一个声明性的、简单、快速且有趣的包,用于用 Go 构建命令行工具。 二、快速使用 2.1 引入依赖 go get github.com/urfave/cli/v2 2.2 demo package mainimport ("fmt""log""os""github.com/ur…...

四种应用层协议——MQTT、CoAP、WebSockets和HTTP——在工业物联网监控系统中的性能比较
目录 摘要(Abstract) 实验设置 实验结果 节选自《A Comparative Analysis of Application Layer Protocols within an Industrial Internet of Things Monitoring System》,作者是 Jurgen Aquilina、Peter Albert Xuereb、Emmanuel Francalanza、Jasmine Mallia …...

MySQL的脏读、不可重复读、幻读与隔离级别
脏读/不可重复读/幻读 脏读 脏读(Dirty Read)发生在一个事务读取了另一个事务尚未提交的数据。如果第二个事务失败并回滚,第一个事务读到的数据就是错误的。这意味着数据从一开始就是不稳定或者“脏”的。 举例 事务A读取了某条记录的值为X。事务B修改该记录的值…...

程序员前端开发者的AI绘画副业之路:在裁员危机中寻找新机遇
正文: 在这个充满变数的时代,作为一名前端开发者,我经历了行业的起伏,见证了裁员危机和中年失业危机的残酷。在这样的背景下,我开始了利用AI绘画作为副业的探索,不仅为了寻求经济上的稳定,更是为…...

Burp Suite的使用和文件上传漏洞靶场试验
第一步:分析如何利用漏洞,通过对代码的查阅发现,代码的逻辑是先上传后删除,意味着,我可以利用webshell.php文件在上传到删除之间的间隙,执行webshell.php的代码,给上级目录创建一个shell.php木马…...

如何在Ubuntu中安装deepin wine版的企业微信
如何在Ubuntu中安装deepin wine版的企业微信 运行如下一条命令将移植仓库添加到系统中 wget -O- https://deepin-wine.i-m.dev/setup.sh | sh自此以后,你可以像对待普通的软件包一样,使用apt-get系列命令进行各种应用安装、更新和卸载清理了。 安装企业…...

案例:Nginx + Tomcat集群(负载均衡 动静分离)
目录 案例 案例环境 案例步骤 部署Tomcat服务器 部署Nginx服务器 实现负载均衡和读写分离 日志控制 案例 案例环境 操作系统 IP 地址 角色 CentOS 192.168.10.101 Nginx服务器(调度器) CentOS 192.168.10.102 Tomcat服务器① CentOS 1…...
【密码学】密码协议的分类:②认证协议
密码协议的分类有很多种方式,这里我采取的是基于协议实现的目的来分类。可以将密码协议分成三类:认证协议、密钥建立协议、认证密钥建立协议。 一、认证协议是什么? 认证协议都在认证些什么东西呢?认证一般要认证三个东西&#x…...

异步编程(Promise详解)
目录 异步编程 回调函数 回调地狱 Promise 基本概念 Promise的特点 1.Promise是一种构造函数 2.Promise接收函数创建实例 3.Promise对象有三种状态 4.Promise状态转变不可逆 5.Promise 实例创建即执行 6.Promise可注册处理函数 7.Promise支持链式调用 Promise的静…...

DjangoORM注入分享
DjangoORM注入 简介 这篇文章中,分享一些关于django orm相关的技术积累和如果orm注入相关的安全问题讨论。 攻击效果同数据库注入 从Django-Orm开始 开发角度 Django ORM(Object-Relational Mapping)是Django框架中用于处理数…...

【HBZ分享】Redis各种类型的数据结构应用场景
String(字符串类型) 计数器: incr / decr, 比如商品库存,业务号的发号器业务数据key-value缓存, 缓存结果数据,提高网站性能,缓解DB压力分布式session会话, 集群环境下存储token鉴权信息分布式锁ÿ…...

anaconda创建并且配置pytorch(完整版)
📚博客主页:knighthood2001 ✨公众号:认知up吧 ** 🎃知识星球:【认知up吧|成长|副业】介绍** ❤️如遇文章付费,可先看看我公众号中是否发布免费文章❤️ 🙏笔者水平有限,欢迎各位大…...

高级java每日一道面试题-2024年8月10日-网络篇-你对跨域了解多少?
如果有遗漏,评论区告诉我进行补充 面试官: 你对跨域了解多少? 我回答: 跨域问题,即Cross-Origin Resource Sharing(CORS),是现代Web开发中一个非常重要的概念,涉及到浏览器的安全策略——同源策略(Same…...

AtCoder Beginner Contest 365 A~E
A.Leap Year(思维) 题意: 给你一个介于 1583 1583 1583和 2023 2023 2023之间的整数 Y Y Y。 求公历 Y Y Y年的天数。 在给定的范围内, Y Y Y年的天数如下: 如果 Y Y Y不是 4 4 4的倍数,则为 365 365 …...

多机部署, 负载均衡-LoadBalance
目录 1.负载均衡介绍 1.1问题描述 1.2什么是负载均衡 1.3负载均衡的一些实现 服务端负载均衡 客户端负载均衡 2.Spring Cloud LoadBalancer 2.1快速上手实现负载均衡 2.2负载均衡策略 自定义负载均衡策略 3.服务部署(Linux) 3.1服务构建打包…...

(回溯) LeetCode 78. 子集
原题链接 一. 题目描述 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的 子集 (幂集)。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1: 输入:nums [1,2,3] 输出&…...

DQL数据查询语言(多表处理)—/—<7>
一、多表处理 当前有两个表,一个是学生表student,一个是分数表score student表字段名表示如下(共1000条数据): score表字段表示如下(共6000条数据): 1、求每个学生的总分 SELECT …...

力扣刷题总结
去年有段时间一直在刷题,进步神速,解决了以往刷完就忘的问题,这里总结下经验,给有需要的人参考下,核心观点就仨: 1. 打好数据结构与算法基础 2. 多刷题多练习 3. 形成自己的知识体系 下图是我梳理的知识体…...

BLDC ESC 无刷直流电子调速器驱动方式
BLDC ESC 无刷直流电子调速器驱动方式 1. 源由2. 驱动方法2.1 Trapezoidal 1202.2 Trapezoidal 1502.3 Sinusoidal 1802.4 Field-Orientated Control (FOC) 3. FOC(Field-Oriented Control)3.1 引入坐标系3.2 Clarke and Park变换Clarke 变换(…...

解决 IntelliJ IDEA 编译错误 “Groovyc: Internal groovyc error: code 1” 及 JVM 内存配置问题
在使用 IntelliJ IDEA 进行开发时,我们可能会遇到各种编译和运行错误,其中之一就是 Groovy 编译器错误(Groovyc: Internal groovyc error: code 1)或 JVM 内存不足错误。这类错误可能会影响开发效率,但通过调整 JVM 内…...

LeetCode.2940.找到Alice和Bob可以相遇的建筑
友情提示:这个方法并没有通过案例,只通过了944个案例(很难受),超时了,但是想着还是分享出来吧 题目描述: 给你一个下标从 0 开始的正整数数组 heights ,其中 heights[i] 表示第 i …...