数据结构与算法 知识点整理

线性表

线性表的基本概念

线性表的定义:线性表是一个具有相同特性的数据元素的有限序列。

相同特性:所有元素属于同一数据类型

有限:数据元素个数是有限的

序列:数据元素由逻辑序号(逻辑位序)唯一确定,一个线性表中可以有相同值的元素

线性表的基本运算

1. 初始化线性表:构造一个空的线性表

2. 销毁线性表

3. 判断线性表是否为空

4. 求线性表的长度

5. 输出线性表

6. 求线性表中指定位置的数据元素

7. 定位查找特定值的数据元素

8. 插入

9. 删除

线性表的顺序存储结构

按逻辑顺序依次存储到存储器中一片连续的存储空间中。

顺序表类型定义

顺序表的运算实现

#include<stdio.h>
#include<stdlib.h>#define ElemType char
#define MaxSize 100typedef struct {ElemType data[MaxSize];int length;
} SqList;//初始化顺序表
void InitList(SqList*& L) {L = (SqList*)malloc(sizeof(SqList));L->length = 0;
}//整体创建顺序表
void CreateList(SqList*& L, ElemType a[], int n) {L = (SqList*)malloc(sizeof(SqList));for (int i = 0; i < n; i++) {L->data[i] = a[i];}L->length = n;
}//销毁顺序表
void DestroyList(SqList*& L) {free(L);
}//判断是否为空表
bool ListEmpty(SqList*& L) {return L->length == 0;
}//求顺序表长度,直接返回length值即可
int ListLength(SqList*& L) {return L->length;
}//输出顺序表
void DispList(SqList*& L) {if (ListEmpty(L)) return; //这样不会多打印一个换行符for (int i = 0; i < L->length; i++) {printf("%c ", L->data[i]);}putchar('\n');
}//求第i个元素的值(i从1开始),放到e里面
bool GetElem(SqList*& L, int i, ElemType& e) {if (i < 1 || i > L->length) return false;e = L->data[i - 1];return true;
}//查找第一个值域与e相等的元素的逻辑位序(从1开始),找不到就返回0
int LocateElem(SqList*& L, ElemType e) {int i = 0;while (i < L->length && L->data[i] != e) {++i;}if (i == L->length) return 0;else return i + 1;// 逻辑位序和物理位序相差1
}// 在第i个位置(逻辑位序)插入新元素
bool InsertList(SqList*& L, int i, ElemType e) {// 检查一下输入的合法性if (i < 1 || i > L->length) return false;--i;// 把逻辑位序转化成物理位序,对于coder来说好操作;此后,i即物理位序// 把第i...length-1个元素都往后挪一位,把第i个位置腾出来for (int j = L->length - 1; j >= i; --j) {L->data[j + 1] = L->data[j];}L->data[i] = e;L->length += 1;// 注意顺序表的长度是我们需要去维护的!return true;
}// 删除第i个位置的数据元素,返回给e
bool DeleteList(SqList*& L, int i, ElemType& e) {// 检查输入合法性if (i < 1 || i > L->length) return false;--i;e = L->data[i];for (int j = i + 1; j < L->length; j++) {L->data[j] = L->data[j - 1];}L->length += 1; // 差点又忘记维护了!呜呜呜return true;
}

顺序表算法设计(进阶)

1. 已知长度为n的线性表A采用顺序存储结构。设计一个时间复杂度为On、空间复杂度为O1的算法,该算法删除线性表中所有值为x的数据元素。

算法1:空间复用,还算好理解

// 算法1,空间复用,直接覆盖
void DelAl1(SqList*& L, ElemType x) {int k = 0;for (int i = 0; i < L->length; i++) {if (L->data[i] != x) {L->data[k] = L->data[i];++k;}}L->length = k;
}

算法2:稍微有点抽象了

这个题目的难点在于时间复杂度的要求,On也就是说我们只能遍历一遍,在这唯一的一次遍历中完成所有移位操作。但是我们一开始肯定会想,当我第一次遍历,面对一个元素的时候,我怎么知道要把这个元素前移几位呢?

事实上这是可知的!你仔细想想,如果这个元素前面有x个需要移除的元素,那你是不是把这个元素往前移x位即可?

注意,k计数的是“需要被移除”的元素个数!所以最后顺序表的长度为原长-k

// 算法2,有点抽象
void DelAl2(SqList*& L, ElemType x) {int k = 0;for (int i = 0; i < L->length; i++) {if (L->data[i] == x) ++k;else {L->data[i - k] = L->data[i];}}L->length -= k;
}

2. 设顺序表L有10个整数。设计一个算法,以第一个元素为分界线,将所有小于等于它的元素移到该元素的前面,将所有大于它的元素移到该元素的后面。

void MoveAl1(SqList*& L) {ElemType pivot = L->data[0];int i = 0, j = L->data[L->length - 1];while (i < j) {//i < j这个条件必须一直约束着while (i < j && L->data[i] <= pivot) {//小于等于的话,那你就一边玩去,没你事儿~++i;}while (i < j && L->data[i] > pivot) {++j;}if (i < j) {ElemType temp = L->data[i];L->data[i] = L->data[j];L->data[j] = temp;}}ElemType temp = L->data[0];L->data[0] = L->data[i];L->data[i] = temp;
}

线性表的链式存储结构

单链表:每个物理节点增加一个指向后继节点的指针域

双链表:每个物理节点增加一个指向后继节点的指针域和一个指向前驱节点的指针域

这里提出一个存储密度的概念:

单链表中节点类型LinkList的定义

typedef struct LNode{ElemType data;struct LNode* next;
} LinkList;

单链表建表——头插法、尾插法

头插法:

1. 从一个空表开始,创建一个头节点dummyHead。

2. 依次读取字符数组中的元素,生成新节点。

3. 将新节点插入到当前链表的表头上,直到结束为止。

(注意:链表的节点顺序与逻辑次序相反)

//头插法建表
void CreateListByHead(LinkList*& L, ElemType a[], int n) {L = (LinkList*)malloc(sizeof(LinkList));L->next = NULL;for (int i = 0; i < n; i++) {LNode* newNode = (LNode*)malloc(sizeof(LNode));newNode->data = a[i];newNode->next = L->next;L->next = newNode;}
}

尾插法:

1. 从一个空表开始,创建一个头节点dummyHead。

2. 依次读取字符数组a中的元素,生成新节点。

3. 将新节点插入到当前链表的表尾上,直到结束为止。

(链表的节点顺序与逻辑次序相同)

单链表的基本运算

单链表的算法设计

以查找为基础

1. 设计一个算法,删除一个单链表L中元素值最大的节点(假设最大值节点是唯一的)

// 删除最大节点
void DelMaxNode(LinkList*& L) {if (ListEmpty(L)) return;LNode* pre = L, * maxPre = L;while (pre->next != NULL) {if (pre->next->data > maxPre->next->data) {maxPre = pre;}pre = pre->next;}maxPre->next = maxPre->next->next; //不会出现空指针异常!因为maxPre后面一定是指着一个节点的!
}

2. 有一个带头节点的单链表L(至少有一个数据节点),设计一个算法使其元素递增有序排列。

我不懂

// 排序算法,我不懂
void SortList(LinkList*& L) {LNode* p = L->next, * pre;LNode* r = p->next;// r作为p放入后继,防止断链p->next = NULL; // 构造只有一个数据节点的有序表p = r;while (p != NULL) {r = p->next;// r防止断链,又接回去了?!pre = L;while (pre->next != NULL && pre->next->data < p->data) {pre = pre->next;}p->next = pre->next;pre->next = p;p = r;}
}

把链表转化成数组问题貌似可以,毕竟对数组进行排序的算法可多了。 

以建表为基础

1. 假设有一个带头节点的单链表L,设计一个算法将所有节点逆置。

用头插法不就是直接形成一个逆置链表了嘛!

// 逆置链表
void ReverseList(LinkList*& L) {LinkList* p = L->next, * q;L->next = NULL;while (p != NULL) {q = p->next;p->next = L->next;L->next = p;// 让p成为逆置链表的新的头节点p = q;}
}

栈的基本概念

栈的定义:只能在一端进行插入或删除操作的线性表

允许进行插入、删除操作的一端——栈顶

栈的顺序存储结构

顺序栈的基本运算实现

#include<stdio.h>
#include<stdlib.h>#define ElemType int
#define MaxSize 10typedef struct {ElemType data[MaxSize];int top;
} SqStack;// 初始化栈,创建一个空栈
void InitStack(SqStack*& S) {S = (SqStack*)malloc(sizeof(SqStack));S->top = -1;
}// 销毁栈
void DstroyStack(SqStack*& S) {free(S);
}// 判断栈是否为空,若栈为空则返回true
bool StackEmpty(SqStack*& S) {return (S->top == -1)
}// 进栈
bool PushStack(SqStack*& S, ElemType e) {// 顺序栈可能出现栈满的情况if (S->top == MaxSize - 1) {return false;}S->top++;S->data[S->top] = e;return true;
}// 出栈
bool PopStack(SqStack*& S, ElemType& e) {if (StackEmpty(S)) {return false;}e = S->data[S->top];S->top--;return true;
}// 取栈顶元素
bool GetTop(SqStack*& S, ElemType& e) {if (StackEmpty(S)) {return false;}e = S->data[S->top];return true;
}

顺序栈的算法设计

栈这种先进后出的思想可以用来解决“回文字符串”问题

1. 设计一个算法利用顺序栈判断一个字符串是否是对称串

// 判断回文字符串
bool SymmetryString(ElemType str[]) {SqStack* st;ElemType temp;InitStack(st);for (int i = 0; str[i]; i++) {PushStack(st, str[i]);}for (int i = 0; str[i]; i++) {PopStack(st, temp);if (temp != str[i]) {return false;}}DestroyStack(st);return true;
}

栈的链式存储结构

头插法,链表的真实头节点即栈顶

链式栈的基本运算实现

#include<stdio.h>
#include<stdlib.h>#define ElemType chartypedef struct LinkNode {ElemType data;LinkNode* next;
} LkStack;// 初始化栈
void InitStack(LkStack*& S) {S = (LkStack*)malloc(sizeof(LkStack));S->next == NULL;
}// 销毁栈
void DestroyStack(LkStack*& S) {LinkNode* p = S->next, *q;while (p != NULL) {q = p->next;free(p);p = q;}free(S);
}// 判断栈是否为空
bool StackEmpty(LkStack*& S) {return (S->next == NULL);
}// 进栈
void PushStack(LkStack*& S, ElemType e) {LinkNode* newNode = (LinkNode*)malloc(sizeof(LinkNode));newNode->data = e;newNode->next = S->next;S->next = newNode;
}// 出栈,出栈可能失败因此返回值设置为bool
bool PopStack(LkStack*& S, ElemType &e) {if (StackEmpty(S)) {return false;}e = S->next->data;LinkNode* temp = S->next;S->next = temp->next;free(temp);return true;
}// 取栈顶元素
bool GetTop(LkStack*& S, ElemType &e) {if (StackEmpty(S)) {return false;}e = S->next->data;return true;
}// 遍历栈
bool DispStack(LkStack*& S) {if (StackEmpty(S)) {return false;}LinkNode* p = S->next;while (p != NULL) {printf("%c\n", p->data);p = p->next;}
}int main() {LkStack* st;InitStack(st);PushStack(st, 'a');DispStack(st);return 0;
}

链式栈的算法设计

1. 编写一个算法判断表达式的左右括号是否匹配(假设只含有左右圆括号)

//  判断表达式的左右括号是否匹配
bool IsMatch(char expr[]) {LkStack* st;ElemType e;InitStack(st);for (int i = 0; expr[i]; i++) {// 遇到左括号就把左括号入栈if (expr[i] == '(') {PushStack(st, expr[i]);}else if (expr[i] == ')') {if (GetTop(st, e)) {if (e == '(') {PopStack(st, e);}else {return false;}}}}// 如果遍历完整个字符串之后,栈刚好为空,则返回trueif (StackEmpty(st)) {DestroyStack(st);return true;}else {DestroyStack(st);return false;}
}

需要注意的点是:你对几个栈的基本函数必须熟悉啊!返回值是多少?参数列表如何设定?

比如你用到PopStack这个函数,你是把Pop出去的那个元素的值放到e里面,你是这么些PopStack(st,e),然后你再对e这个值及逆行判断。

卧槽要是你直接写if(PopStack(st,e) == ’)’)不就寄了。

队列

队列是一种运算受限的线性表。

插入是从队尾插入(很合理,我们排队也是从队尾开始排队呢)

队列的顺序存储结构-顺序队

顺序队的基本算法实现

#include<stdio.h>
#include<stdlib.h>#define ElemType char
#define MaxSize 10typedef struct {ElemType data[MaxSize];int front, rear; // 定义队头和队尾
} SqQueue;// 初始化队列
void InitQueue(SqQueue*& Q) {Q = (SqQueue*)malloc(sizeof(SqQueue));Q->front = Q->rear = -1;
}// 销毁队列
void DestroyQueue(SqQueue*& Q) {free(Q);
}// 判断队列是否为空
bool QueueEmpty(SqQueue*& Q) {return (Q->front == Q->rear);
}// 进队列
bool InQueue(SqQueue*& Q, ElemType e) {// 顺序队要先判断是否队满if (Q->rear == MaxSize - 1) {return false;}Q->rear++;Q->data[Q->rear] = e;return true;
}// 出队列
bool OutQueue(SqQueue*& Q, ElemType &e) {if (QueueEmpty(Q)) {return false;}Q->front++;e = Q->data[Q->front];return true;
}

环形顺序队

为什么rear需要+1,因为,你要进队啊!那你不得把指针往后挪一位。为什么要取余,因为是环形队列,这里有一个循环,尾接着头。

为什么front需要+1,因为front指向的是队头的前一个节点,你要把front+1之后才能确切指向队头。取余原因同理

#include<stdio.h>
#include<stdlib.h>#define ElemType char
#define MaxSize 10typedef struct {ElemType data[MaxSize];int front;int count; // 设置一个count保存元素个数
} CQueue;// 初始化队列
void InitQueue(CQueue*& CQ) {CQ = (CQueue*)malloc(sizeof(CQueue));CQ->front = CQ->count = 0;
}// 入队
bool InQueue(CQueue*& CQ, ElemType e) {if (CQ->count == MaxSize) {return false;}int rear = (CQ->front + CQ->count) % MaxSize;rear = (rear + 1) % MaxSize;// 加1是一定要加1的,环形队列是需要取余的。CQ->data[rear] = e;CQ ->count++;return true;
}// 出队
bool OutQueue(CQueue*& CQ, ElemType& e) {// 这里不需要判断为空函数了,count直接保存该队列的元素值,注意维护!if (CQ->count == 0) {return false;}CQ->front = (CQ->front + 1) % MaxSize;e = CQ->data[CQ->front];CQ->count--;return true;
}

队列的链式存储结构-链式队

#include<stdio.h>
#include<stdlib.h>#define ElemType chartypedef struct qNode {ElemType data;struct qNode* next;
} QNode;typedef struct {QNode* front; // 指向链式队头节点QNode* rear; // 指向链式队尾节点
} LkQueue;// 初始化
void InitQueue(LkQueue*& LQ) {LQ = (LkQueue*)malloc(sizeof(LkQueue));LQ->front = LQ->rear = NULL;
}// 销毁
void DestroyQueue(LkQueue*& LQ) {QNode* p = LQ->front, *q;while (p != NULL) {q = p->next;free(p);p = q;}free(LQ);
}// 判断队列是否为空
bool QueueEmpty(LkQueue*& LQ) {return (LQ->front == NULL);
}// 进队
void InQueue(LkQueue*& LQ, ElemType e) {QNode* newNode = (QNode*)malloc(sizeof(QNode));newNode->data = e;newNode->next = NULL;if (QueueEmpty(LQ)) {LQ->front = LQ->rear = newNode;}else {LQ->rear->next = newNode;LQ->rear = newNode;}
}bool OutQueue(LkQueue*& LQ, ElemType &e) {if (QueueEmpty(LQ)) {return false;}QNode* temp = LQ->front;LQ->front = temp->next;e = temp->data;// 如果只有一个节点,那要对rear也进行修改if (temp->next == NULL) {free(temp);LQ->front = LQ->rear = NULL;}else {LQ->front = temp->next;free(temp);}return true;
}// 遍历
bool DispQueue(LkQueue*& LQ) {if (QueueEmpty(LQ)) {return false;}QNode* p = LQ->front;while (p != NULL) {printf("%c ", p->data);p = p->next;}
}int main() {LkQueue* LQ;InitQueue(LQ);InQueue(LQ, 'a');InQueue(LQ, 'b');InQueue(LQ, 'c');ElemType e;OutQueue(LQ, e);DispQueue(LQ);return 0;
}

环形链式队

栈和队列的应用

1. 简单表达式求值

postfix后缀表达式计算

好的,那么问题来了,我们如何将infix转换为postfix呢?

没括号情况

有括号情况

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

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

相关文章

Oracle SQL Developer导出数据库表结构,表数据,索引以及序列号等对象

目录 一、业务需求 三、环境说明 三、数据导出 四、数据导入 一、业务需求 通过Oracle SQL Developer软件将指定oracle数据库中的表结构&#xff0c;表数据&#xff0c;索引以及序列号等对象导出成SQL文件。 三、环境说明 数据库版本&#xff1a;Oracle Database 11g Expres…

【管理篇】如何向上沟通?

目录标题 向上沟通中下列问题最普遍和上级能不聊就不聊拿捏不好该不该和上级聊的分寸和尺度很难领会到上级的意图如何影响上级的一些观点和决策? 如何应对上述问题呢&#xff1f;&#x1f60e;如何管理上级&#xff1f;&#x1f44c; 向上沟通中下列问题最普遍 和上级能不聊就…

sql函数--10---In 多个字段

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.普通 in语句查询sqlMyBatis错误写法正确写法ListString[] 2.In多个字段sql案例脚本实例&#xff1a;错误写法&#xff1a;正确写法&#xff1a; MyBatis XML 写法…

Spring 事务及事务传播机制(1)

目录 事务 回顾: 什么是事务 为什么需要事务 事务的操作 Spring事务的实现 Spring编程式事务(简单了解即可, 问就是基本不用) 观察事务提交 观察事务回滚 Spring声明式事务 Transactional Transactional作用 事务 回顾: 什么是事务 定义: 事务是指逻辑上的一组操作, 构…

语义分割——前列腺分割数据集

引言 亲爱的读者们&#xff0c;您是否在寻找某个特定的数据集&#xff0c;用于研究或项目实践&#xff1f;欢迎您在评论区留言&#xff0c;或者通过公众号私信告诉我&#xff0c;您想要的数据集的类型主题。小编会竭尽全力为您寻找&#xff0c;并在找到后第一时间与您分享。 …

JVM认识之垃圾收集算法

一、标记-清除算法 1、定义 标记-清除算法是最基础的垃圾收集算法。它分为标记和清除两个阶段。先标记出所有需要回收的对象&#xff08;即垃圾&#xff09;&#xff0c;在标记完成后再统一回收所有垃圾对象。 2、优点和缺点 优点&#xff1a;实现简单缺点&#xff1a; 可能…

初阶数据结构之单链表详解

目录 一&#xff1a;单链表概念 二&#xff1a;单链表的基本操作 1.定义结点 2.创建链表&#xff08;初始化链表&#xff09; 3:新增结点 4.单链表尾插 5.单链表头插 6.单链表尾删 7&#xff1a;单链表头删 8.打印单链表 9.查找单链表结点 10.单链表删除指定结点 1…

Centos7 安装 MySQL5.7 使用 RPM 方式

1 访问网站 https://downloads.mysql.com/archives/community/ 选择合适的版本&#xff0c;点击 Download。 2 上传下载好的 mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar 文件到 Centos7 机器&#xff0c;这里放到了 下载 目录。 3 解压 mysql-5.7.44-1.el7.x86_64.rpm-bundle.…

JS笔试手撕题

数据劫持 Vue2的Object.defineProperty() Vue2的响应式是通过Object.defineProperty()拦截数据&#xff0c;将数据转换成getter/setter的形式&#xff0c;在访问数据的时候调用getter函数&#xff0c;在修改数据的时候调用setter函数。然后利用发布-订阅模式&#xff0c;在数…

基于PSO粒子群优化的配电网可靠性指标matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 PSO算法应用于配电网优化的基本原理 5.完整程序 1.程序功能描述 基于PSO粒子群优化的配电网可靠性指标matlab仿真&#xff0c;指标包括saifi, saidi, caidi, aens四个。 2.测试软件版本…

深度学习--DCGAN

代码之后的注释和GAN的一样&#xff0c;大家如果已经掌握GAN&#xff0c;可以忽略掉哦&#xff01;&#xff01;&#xff01; 在学习DCGAN之前&#xff0c;我们要先掌握GAN&#xff0c;深度学习--生成对抗网络GAN-CSDN博客 这篇博客讲的就是GAN的相关知识&#xff0c;还是很详…

POST请求

1、代码 import urllib.request import urllib.parse# 指定 URL url https://fanyi.baidu.com/sug# POST 请求携带的参数进行处理流程&#xff1a; # 1. 将 POST 请求参数封装到字典 data {kw: 西瓜 }# 2. 使用 parse 模块中的 urlencode 进行编码处理 data urllib.parse.u…

【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十篇&#xff1a;Java中线程安全、锁讲解。 当涉及到多线程编程时&#xff0c;保证线程安全是至关重要的。线程安全意味着在多个线程访问共享资源时&#xff0c;不会发生数据错乱或不一致的情况。为了实现线程安全&am…

JavaScript异步编程——05-回调函数

我们在前面的文章《JavaScript 基础&#xff1a;异步编程/单线程和异步》中讲过&#xff0c;Javascript 是⼀⻔单线程语⾔。早期我们解决异步场景时&#xff0c;⼤部分情况都是通过回调函数来进⾏。 &#xff08;如果你还不了解单线程和异步的概念&#xff0c;可以先去回顾上一…

【Redis7】10大数据类型之Zset类型

文章目录 1.Zset类型2.常用命令3.示例3.1 ZADD,ZRANGE和ZREVRANGE3.2 ZSCORE,ZCARD和ZREM3.3 ZRANGEBYSCORE和ZCOUNT3.4 ZRANK和ZREVRANK3.5 Redis7新命令ZMPOP 1.Zset类型 Redis的Zset&#xff08;Sorted Set&#xff0c;有序集合&#xff09;是一种特殊的数据结构&#xff0…

Encoder——Decoder工作原理与代码支撑

神经网络算法 &#xff1a;一文搞懂 Encoder-Decoder&#xff08;编码器-解码器&#xff09;_有编码器和解码器的神经网络-CSDN博客这篇文章写的不错&#xff0c;从定性的角度解释了一下&#xff0c;什么是编码器与解码器&#xff0c;我再学习笔记补充的时候&#xff0c;讲一下…

TMS320F28335学习笔记-时钟系统

第一次使用38225使用了普中的clocksystem例程进行编译&#xff0c;总是编译失败。 问题一&#xff1a;提示找不到文件 因为工程的头文件路径没有包含&#xff0c;下图的路径需要添加自己电脑的路径。 问题二 找不到库文件 例程种的header文件夹和common文件夹不知道从何而来…

【Alluxio】文件系统锁模型之InodeLockList

InodeLockList接口,表示在inode tree里一个加了锁的路径。 沿着path,inodes和edges都被加锁了。path可能从edge或inode任意一个开始。 锁列表总是包含了一定数量的读锁(0个或多个),随后跟随着一些数量的写锁(0个或多个)。 举个例子: 对 /a/b/c/d 进行加锁,c->d这…

【深度学习】网络安全,SQL注入识别,SQL注入检测,基于深度学习的sql注入语句识别,数据集,代码

文章目录 一、 什么是sql注入二、 sql注入的例子三、 深度学习模型3.1. SQL注入识别任务3.2. 使用全连接神经网络来做分类3.3. 使用bert来做sql语句分类 四、 深度学习模型的算法推理和部署五、代码获取 一、 什么是sql注入 SQL注入是一种常见的网络安全漏洞&#xff0c;它允许…

【进程间通信】共享内存

文章目录 共享内存常用的接口指令利用命名管道实现同步机制总结 System V的IPC资源的生命周期都是随内核的。 共享内存 共享内存也是为了进程间进行通信的&#xff0c;因为进程间具有独立性&#xff0c;通信的本质是两个不同的进程看到同一份公共资源&#xff0c;所以共享内存…