数据结构- 顺序表-单链表-双链表 --【求个关注!】

文章目录

  • 一 顺序表
    • 代码:
  • 二 链表
    • 单链表
    • 双向链表


一 顺序表

顺序表是线性表的一种
所谓线性表指一串数据的组织存储在逻辑上是线性的,而在物理上不一定是线性的
顺序表的底层实现是数组,其由一群数据类型相同的元素组成,其在逻辑与物理上均是线性的。

代码:

对于顺序表的结构及各种操作函数的声明
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include <assert.h>
#include<string.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>//顺序表的声明
typedef int Datatype;  //规定顺序表的基本元素是什么类型
struct SeqList {Datatype* arr;   //顺序表空间的首地址int size;        //顺序表中当前元素的个数int capacity;    //顺序表当前所申请的空间个数,单位为数据类型大小
};//初始化一个顺序表的声明
void Initialize(struct SeqList* ps);
// 插入数据操作
//尾插法
void TailInsert(struct SeqList* ps, Datatype x);
//头插法
void HeadInsert(struct SeqList* ps, Datatype x);
//在指定位置插入数据
void RanInsert(struct SeqList* ps, int pos, Datatype x);
//删除数据操作
//头删法
void HeadDelete(struct SeqList* ps);
//尾删法
void TailDelete(struct SeqList* ps);
//在指定位置删除数据
void RanInsert(struct SeqList* ps, int pos);
//查找数据,返回下标
int Select(struct SeqList* ps, Datatype x);//删除顺序表的声明
void DeleteList(struct SeqList* ps);

对于顺序表及各种操作函数的实现:
在这里插入图片描述

#include "seqlist.h"
// 初始化一个顺序表
void Initialize(struct SeqList * ps) {//初始化地址ps->arr = NULL;  //NULL在文件string.h中定义ps->size = ps->capacity = 0;
}
// 判断空间是否够用,不够的话申请空间
void DeterSpace(struct SeqList* ps) {if (ps == NULL) {perror("ps");}if (ps->size == ps->capacity) {// 如果并未分配空间,返回int  exsp = ps->capacity == 0 ? 4 : 2 * ps->capacity;ps->capacity = exsp; //将扩展后的空间大小记录下来Datatype* p1 = NULL;// 扩展空间大小p1 = realloc(ps->arr, exsp * sizeof(Datatype));assert(p1);ps->arr = p1;}}
//尾插法
void TailInsert(struct SeqList* ps, Datatype x) {if (ps == NULL) {perror("ps");}//需要先确定空间是否够用?//如果顺序表中的元素个数等于空间大小,则需要扩展空间--申请原来空间两倍的空间DeterSpace(ps);// 将值插到顺序表末尾ps->arr[ps->size++] = x;}
// 头插法:
void HeadInsert(struct SeqList* ps, Datatype x) {//对于头插法,我们也需要判断空间是否足够用DeterSpace(ps);//在保证了空间之后,将顺序表中数据先往右移动一个元素大小,再进行插入for (int i = ps->size; i > 0; i--) {ps->arr[i] = ps->arr[i - 1];}//空出首地址之后:ps->arr[0] = x;//元素的个数也需要++ps->size++;
}
// 在指定位置插入一个数据
void RanInsert(struct SeqList *ps,int pos,Datatype x) {assert(ps);assert(pos>=0 &&pos<=ps->size -1);//在指定位置插入一个数据可以由 将此位置及此位置以后的数据往后移动一位,然后再将数据插入此位置//在此之前要判断空间是否够用DeterSpace(ps);for (int i = ps->size-1; i >= pos; i--) {ps->arr[i+1] = ps->arr[i]; //将pos在内之后的数据往右移动一位}ps->arr[pos] = x;ps->size++;
}
// 头删法  
// 即删除顺序表中的首个元素
void HeadDelete(struct SeqList* ps) {for (int i = ps->size - 1; i > 0; i++) {ps->arr[i - 1] = ps->arr[i];}ps->arr[ps->size - 1] = 0;ps->size--;
}
// 尾删法  -- 找到最后一个数组元素置为0;
void TailDelete(struct SeqList* ps) {//直接通过ps->size找到顺序表中最后一个元素置为0ps->arr[ps->size - 1] = 0;ps->size--;}
// 删除指定位置的数据 
void RanInsert(struct SeqList*ps,int pos) {//我们删除指定位置的数据后,可以由在此位置之后的数据整体往前移动来实现assert(ps);assert(0 <= pos && pos <= ps->size - 1);//在下标pos之前的数据向前移动for (int i = ps->size - 1; i > pos; i--) {ps->arr[i - 1] = ps->arr[i]; }ps->arr[ps->size - 1] = 0;//将顺序表原来的最后一个元素位置置为0;ps->size--; // 元素个数-1}
// 查找
// 返回相应的下标
int Select(struct SeqList * ps,Datatype x) {assert(ps);for (int i = 0; i < ps->size - 1; i++) {if (ps->arr[i] == x) {return i;}}//找不到返回0return 0;}
// 删除一个顺序表
void DeleteList(struct SeqList* ps) {if (ps == NULL) {exit(1);}free(ps->arr);ps->arr = NULL;//并将元素个数,空间记录清除ps->size = ps->capacity = 0;}

二 链表

链表是线性表的一种
1   链表的逻辑结构是线性的,但其物理存储结构不是线性的。
2   链表的基本元素为结点,结点由数据域与指针域组成,数据域中存放存储的数据,
指针域中存放指向其他结点的指针, 结点之间通过指针互相联系。
链表共有8种(2*2*2)
链表的三种特性分别为:      带头与不带头( 所谓头即指不携带有效数据的头节点)单向与双向链表循环与不循环(所谓循环即第一个结点与尾结点链接在一起)

链表:

在这里插入图片描述

在这里插入图片描述
最常见的有两种:单链表与双向链表

单链表

单链表的全称是不带头单向不循环链表

我在代码中的注释所写的首节点是可以携带有效数据的,为了避免与头节点混淆,所以我用首节点作为名称,而不是头节点!
在这里插入图片描述

代码:

#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
// 声明单链表结点
// 对链表中数据类型的声明
typedef int Datatype;
typedef struct ListNode {Datatype data;      //结点中的数据struct ListNode* Next;//指向下一个结点的指针
}Node;
//打印链表函数声明
void PrintList(Node* ps);
//创建新结点并赋值的函数声明
Node* CreateNode(Datatype x);
// 插入数据
// 头插
void HeadInsert(Node** phead, Datatype x);
//尾插
void TailInsert(Node** phead, Datatype x);
// 尾删
void TailDelete(Node** phead);
// 头删
void HeadDelete(Node** phead);
// 查找
Node* Select(Node* phead, Datatype x);
// 在指定位置之前插入数据
void RanLeftInsert(Node** phead, Node* pos, Datatype x);
// 在指定位置之后插入数据
// 我们不需要首节点的参数,因为不需要遍历,也不需要在首节点之前插入数据
void RanRightInsert(Node* pos, Datatype x);
// 删除pos位置的结点
void DeleteNode(Node** phead, Node* pos);
// 删除pos之后的结点
void DeleteAfterNode(Node* pos);
// 销毁链表:
void Distory(Node** phead);

在这里插入图片描述
代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include"List.h"
//打印链表函数
void PrintList(Node* ps) {while (ps!=NULL) {printf("%d\n", ps->data);ps = ps->Next;}
}
// 创建新结点:
Node* CreateNode(Datatype x) {Node* newnode = (Node*)malloc(sizeof(Node));if (newnode == NULL) {perror("malloc");exit(1);   //退出程序}newnode->data = x;newnode->Next = NULL;return newnode;//返回新结点的指针
}
// 插入数据
// 头插
void HeadInsert(Node ** phead,Datatype x ) {Node* newnode = CreateNode(x);// 将新节点插入到原链表的首部newnode->Next = *phead;// 将新节点即新链表首节点的地址赋给*phead*phead = newnode;
}//尾插
void TailInsert(Node** phead, Datatype x) {//参数为指向 指定链表的首结点 的指针与要插入的数据//如果链表一开始为空,即phead =NULL时,则ptail->Next则有问题,Node* ptail = *phead;if (* phead == NULL) {* phead = CreateNode(x); //在函数调用结束后,函数中的局部变量会被收回,//形参phead值的改变不会影响到实参,如果采用首节点二重指针// 则可以通过形参改变首节点的指针。}else {//先找到尾结点while (ptail->Next != NULL) {ptail = ptail->Next;}//在找到尾结点后,在尾结点后插入新的结点,并赋值ptail->Next = CreateNode(x);}}
// 尾删
void TailDelete(Node**phead) {//链表不能为空assert(phead && *phead);//我们在删除尾结点之后,尾结点之前的指针就变为野指针,我们需要找到此指针并置为空//当链表只有一个结点时:if ((*phead)->Next == NULL) {free(*phead);*phead = NULL;}else {// 创建存放指向尾结点的指针Node* prev = NULL;Node* ptail = *phead;//查找头节点while (ptail->Next) {// ptail->Next !=	NULL;prev = ptail;ptail = ptail->Next;}//在找到尾结点后:free(ptail);ptail = NULL;//将指向尾结点的指针置为空prev->Next = NULL;}
}
// 头删
void HeadDelete(Node **phead) {assert(phead && *phead); //链表不能为空//在删除首节点之后,我们需要能够找到下一个结点的地址Node* next = (*phead)->Next;//->的优先级比*大free(*phead);*phead = next;
}
// 查找
Node* Select(Node* phead, Datatype x) {Node* sel = phead;while (sel) {if (sel->data == x) {return sel;}sel = sel->Next;}
}
// 在指定位置之前插入数据
void RanLeftInsert(Node**phead,Node *pos,Datatype x) {//因为首节点可能会改变,所以用二级指针作为形参,避免用一级指针无法改变链表的首地址//在指定位置之前插入数据的情况只有图中的三种情况,在链表之前,在链表中,在链表最后一个元素之前assert(phead&& *phead);  assert(pos);          //因为pos不能为空,所以*phead也不能为空,否则*phead为空时,也可以进行头插if (pos == *phead) {//pos在首节点处,这相当于头插法HeadInsert(phead, x);}else {//pos位置在链表中与链表最后一个元素上,操作没有本质区别Node* newnode = CreateNode(x);Node* prev = *phead;while (prev->Next!=pos) {prev = prev->Next;}//当找到了pos之前的prev时:newnode->Next = pos;prev->Next = newnode;}
}
// 在指定位置之后插入数据
// 我们不需要首节点的参数,因为不需要遍历,也不需要在首节点之前插入数据
void RanRightInsert(Node * pos,Datatype x) {assert(pos);//我们先创建新结点Node* newnode = CreateNode(x);//将结点插入到pos之后:newnode->Next = pos->Next;pos->Next = newnode;
}
// 删除pos位置的结点
void DeleteNode(Node** phead, Node* pos) {assert(phead && *phead);assert(pos);//在删除pos结点时,我们需要将pos之后的结点与pos之前的结点链接起来,//pos之后的结点可以用pos->next找到,pos之前的结点需要在遍历时,用变量prev保存!if (pos == *phead) {//当pos是首节点时,此时的情况即头删法HeadDelete(phead);}else {Node* prev = *phead;//在采用这条判断语句的前提是:pos不是首结点while (prev->Next != pos) {prev = prev->Next;}//当找到prev时,将pos之后的结点与pos之前的结点链接起来;prev->Next = pos->Next;//释放掉posfree(pos);}
}
// 删除pos之后的结点
void DeleteAfterNode(Node* pos) {assert(pos && pos->Next);//要删除pos之后的结点,要将pos->next之后的结点与pos链接起来,再删除posNode* del = pos->Next;     pos->Next = del->Next;free(del);//难道此时pos->Next的值不会发生变化?del = NULL;// 兄弟们,下面的c打印的值是多少?它的值会不会随着a的变化而变化呢?//int a = 1;//int c = a;// a++;//printf("%d\n",c);}
// 销毁链表:
void Distory(Node **phead) {assert(phead && *phead);Node* pcur = *phead;while (pcur != NULL) {//链表的销毁需要一个结点一个结点的释放Node* next = pcur->Next;free(pcur);pcur = next;}*phead = NULL;}

在这里插入图片描述

双向链表

双向链表的全称是带头双向循环链表

分析图:

在这里插入图片描述
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS 1
#include<string.h>
#include<assert.h>
#include<stdlib.h>
typedef int Datatype;
//定义双链表结点的格式
typedef struct ListNode {Datatype data;struct ListNode* next;struct ListNode* prev;
}ListNode;
//函数操作的声明:
// 创建结点
void CreateNode(Datatype x);
// 打印链表:
void PrintList(ListNode* phead);
//初始化链表
void Initialize(ListNode** phead);
//插入数据操作
// 尾插法:
// 我们不需要改变头节点,所以用一级指针作为形参即可
void TailInsert(ListNode* phead, Datatype x);
//头插法
void HeadInsert(ListNode* phead, Datatype x);
// 尾删法
void TailDelete(ListNode* phead);
//头删:
void HeadDelete(ListNode* phead);
// 查找
ListNode* Select(ListNode* phead, Datatype x);
// 在指定位置之后插入数据
ListNode* AfterSelect(ListNode* pos, Datatype x);
//删除指定位置pos节点
//pos的形参是一级而不是二级是因为前面的函数形参皆是一级指针 ,这样保证了接口的一致性,确保了
//                                                    他人的方便调用与解读。
void DeleteNode(ListNode* pos, ListNode* phead);
//销毁链表:
void Distory(ListNode* phead);

在这里插入图片描述

#include"List.h"// 打印链表:
void PrintList(ListNode *phead){//我们遍历双向链表的条件是什么?//我们能够找到判断条件是因为,我们知道双向链表从哪里开始到哪里结束是一个循环,我们只是把自己所知道的//用符号的形式表述出来,这是一种能力!ListNode* p1 = phead->next;while(p1 !=phead) {printf("%d\n", p1->data);p1 = p1->next;}
}
//初始化链表
//因为双向链表是带头的【即有头节点】,所以需要先为链表创建一个头节点
void Initialize(ListNode ** phead) {*phead = CreateNode(-1);//创建头节点并随便赋值为1}
//创建新节点并赋值函数
ListNode * CreateNode(Datatype x) {ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));newnode->data = x;
//既然双向链表是循环的,我们在创建结点时,可以先使其自循环!newnode->next = newnode;newnode->prev = newnode;return newnode;	
}
//插入数据操作
// 尾插法:
// 我们不需要改变头节点,所以用一级指针作为形参即可
void TailInsert(ListNode * phead,Datatype x) {ListNode* newnode = CreateNode(x);//创建一个新结点//用phead->prev即可找到尾结点//找到后phead->prev->next = newnode;//将新节点插入到链表尾部newnode->next = phead;newnode->prev = phead->prev; phead->prev = newnode;}
//头插法
void HeadInsert(ListNode* phead, Datatype x) {ListNode* newnode = CreateNode(x);//指针先动谁?//先操作phead->next指向的结点//如果先操作phead结点,则在将phead->next指向新节点后,后面的链表部分就找不到位置了//头插法最多动4个指针:头节点的next,原来第二个结点(可能没有)的prev,新节点的prev与next指针newnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;}
// 尾删法
void TailDelete(ListNode * phead) {// 尾删首先要找到尾结点,然后安排好相应的结点//这是判断链表有效,必须有头节点assert(phead);//这是判断链表不能为空,否则无法删除assert(phead->next!=phead);// phead del del->prev //涉及的节点ListNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;// 删除del节点free(del);del = NULL;}
//头删:
void HeadDelete(ListNode* phead) {assert(phead && phead->next != phead);ListNode* del = phead->next;del->next->prev = phead;
// 删除节点free(del);del = NULL;}
// 查找
ListNode* Select(ListNode* phead,Datatype x) {ListNode* pcur = phead->next;while (pcur != phead) {if (pcur->data == x) {return pcur;}pcur = pcur->next;}//没有找到return NULL;
}
// 在指定位置之后插入数据
ListNode* AfterSelect(ListNode* pos, Datatype x) {assert(pos);ListNode* newnode = CreateNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next->prev = newnode;pos->next = newnode;
}
//删除指定位置pos节点
//pos的形参是一级而不是二级是因为前面的函数形参皆是一级指针 ,这样保证了接口的一致性,确保了
//                                                    他人的方便调用与解读。
void DeleteNode(ListNode * pos,ListNode* phead) {assert(pos && pos != phead);pos->next->prev = pos->prev;pos->prev->next = pos->next;free(pos);pos = NULL;
}
//销毁链表:
void Distory(ListNode*phead) {assert(phead);ListNode* pcur = (phead)->next;while (pcur != NULL) {ListNode* next = pcur->next;free(pcur);pcur = next;}// 此时pcur指向phead,而phead还没有被销毁free(phead);phead = NULL; //为了接口的一致性,不将形参改为ListNode**类型,//则需要在调用函数后,再将实参赋值为NULL;
}

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

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

相关文章

「Word 论文排版」插入分节符导致word转PDF后出现空白页

问题 word转PDF后出现空白页 解决 但是此方法会让页面页脚标记出错 TODO 如下图所示 在论文目录后有一个分节符&#xff0c;转成PDF之后就多了一个空白页 文件-打印-页面设置-选中封面那一页-版式-从偶数页开始 再导出空白页就没了

Java编程题 | 数组元素交换

大家可以关注一下专栏&#xff0c;方便大家需要的时候直接查找&#xff0c;专栏将持续更新~ 题目描述 编写一个Java程序&#xff0c;输入一个整数数组&#xff0c;将最大的元素与第一个元素交换&#xff0c;最小的元素与最后一个元素交换&#xff0c;然后输出修改后的数组…

香港多IP服务器在建立高可用性网站架构中的作用?

香港多IP服务器在建立高可用性网站架构中的作用&#xff1f; 在构建高可用性的网站架构时&#xff0c;选择合适的服务器和配置是至关重要的。香港多IP服务器因其独特的地理和技术优势&#xff0c;成为了全球许多企业的首选。这些服务器由于拥有多个IP地址&#xff0c;能够提供…

OpenHarmony多媒体-mp3agic

简介 mp3agic 用于读取 mp3 文件和读取/操作 ID3 标签&#xff08;ID3v1 和 ID3v2.2 到 ID3v2.4&#xff09;,协助开发者处理繁琐的文件操作相关&#xff0c;多用于操作文件场景的业务应用。 效果展示&#xff1a; 下载安装 ohpm install ohos/mp3agicOpenHarmony ohpm环境配…

Docker Desktop打开一直转圈的解决办法

安装Docker Desktop之前确保你的Hyper-V已经打开 开启后需要重新安装重新安装重新安装这是最关键的一步&#xff0c;博主自己看了很多教程&#xff0c;最后试着重装了一下解决了 安装DockerDesktop的时候我的电脑根本就没有Hyper-V这个功能选项&#xff0c;可能是这个问题 如…

域名信息查询同款WHOIS源码

域名查询一般是指查询域名的whois注册信息&#xff0c;域名WHOIS是当前域名系统中不可或缺的一项信息服务。在使用域名进行Internet冲浪时&#xff0c;很多用户希望进一步了解域名、名字服务器详细信息 源码免费下载地址抄笔记 (chaobiji.cn)https://chaobiji.cn/

力扣打卡第一天

101. 对称二叉树 C&#xff1a; class Solution { public:bool isSymmetric(TreeNode* root) {return check(root->left,root->right);}bool check(TreeNode *p,TreeNode *q){ /**定义check方法用来检查两棵树是否是镜像的*/if (!p && !q) return true; /* 如…

鸿蒙开发语言_ArkTS开发语言体验_TypeScript语言环境搭建_TS声明和数据类型---HarmonyOS4.0+鸿蒙NEXT工作笔记003

可以看到我们新建的这个项目,有个 @State message: String =Hello ArkTS 这个就是定义了一个变量,可以看到 message是变量名,String是变量类型. 然后我们可以看看它的结构可以看到 build() 下面有个Row,然后再下面有个Column方法,然后,里面就是具体的内容了,首先就是显示了一…

Python数据结构【四】排序(二)难度:困难

文章目录 前言一、书接上回二、快速排序&#xff08;Quick Sort&#xff09;2.1 快速排序思想2.2 快速排序代码实现2.3 快速排序复杂度分析 三、堆排序&#xff08;Heap Sort&#xff09;3.1 堆排序思想3.2 堆排序代码实现3.3 堆排序复杂度分析 结语 前言 可私聊进一千多人Pyth…

文件名批量改名,高效将文件名里的符号进行替换删除掉,实现文件名的高效管理

在信息爆炸的时代&#xff0c;我们每天都在与大量的文件打交道。从工作文档到个人照片&#xff0c;从视频剪辑到音频录音&#xff0c;每个文件背后都承载着我们的辛勤付出和美好回忆。然而&#xff0c;随着文件数量的不断增加&#xff0c;如何高效管理这些文件成为了一个亟待解…

MongoDB安装及集成

MongoDB安装及集成 前言 MongoDB是一个开源的、面向文档的 NoSQL 数据库&#xff0c;它采用了 JSON 风格的文档来存储数据&#xff0c;而不是传统的表格形式。MongoDB在数据存储方面具有灵活性和可扩展性&#xff0c;使得它成为了当今流行的数据库之一。 MongoDB的主要特点和…

关于ERA5气压和温度垂直补偿公式的对比情况

1. 气压和温度垂直补偿对比 「谨代表给个人观点&#xff0c;杠精请自测&#xff0c;对对对&#xff0c;好好好&#xff0c;你说啥都对」。 使用2020-2022陆态网GNSS与探空站并址的48个站点实验&#xff0c;以探空站为真值&#xff0c;验证ERA5精度。怎么确定并址请看前面文章…

C++感受6-Hello World 交互版

变量、常量输入、输出、流getline() 函数读入整行输入Hello() 函数复习新定义函数 Input() 实现友好的人机交互还有 “痘痘” 为什么挤不到的分析…… 1. DRY 原则简介 上一节课&#xff0c;我们写了两版“问候”程序。第一版的最大问题是重复的内容比较多&#xff0c;每一次问…

webAssembly学习及使用rust

学习理解 webAssembly 概念知识&#xff0c;使用 API 进行 web 前端开发。 概念 是一种运行在现代网络浏览器中的新型代码&#xff0c;并且提供新的性能特性和效果。它有一种紧凑的二进制格式&#xff0c;使其能够以接近原生性能的速度运行。C/C、 C#、Rust等语言可以编译为 …

RIP小实验配置及缺省路由下发

配置如下&#xff1a; IP配置&#xff1a; IP配置完先查看RIP协议学习到的路由表&#xff0c;没有内容则代表没有开启RIP 启用RIP&#xff1a;这里的rip后跟的ID只具有本地意义&#xff0c;可以在1-65535之间随便取&#xff0c;不同路由器之间都可以取用不同的&#xff0c;为了…

上网行为管理系统功能介绍_上网行为管理实现的功能

上网行为管理系统是一种集成了网络监控、行为分析、策略管理和安全控制等功能的综合性软件解决方案。 它通过对企业内部网络的全面监控和深度分析&#xff0c;帮助管理者了解员工的网络使用习惯、识别潜在风险、优化网络资源配置&#xff0c;并最终实现网络安全和效率的双重提…

对接浦发银行支付(三)-- QR扫码付

一、使用场景 扫码付&#xff0c;指的是支付平台&#xff0c;给每个用户的具体订单生成一个QR二维码&#xff0c;用户本人或者他人扫码付款。 付款用户可以直接识别二维码&#xff0c;或者下载到本地&#xff0c;通过微信或支付宝扫一扫识别&#xff0c;第二步将跳转至对应的支…

详细分析Java中的AuthRequest类(附Demo)

目录 前言1. 基本知识2. Demo3. 实战 前言 公共接口&#xff0c;定义了对第三方平台进行授权、登录、撤销授权和刷新 token 的操作 1. 基本知识 先看源码基本API接口&#xff1a; import me.zhyd.oauth.enums.AuthResponseStatus; import me.zhyd.oauth.exception.AuthExce…

SSDReporter for Mac:全面检测SSD健康,预防数据丢失,让您的Mac运行更稳定

SSDReporter for Mac是一款专为Mac用户设计的固态硬盘&#xff08;SSD&#xff09;健康状况检测工具&#xff0c;旨在帮助用户全面了解并监控其Mac设备中SSD的工作状态&#xff0c;从而确保数据的完整性和设备的稳定性。 这款软件具有多种强大的功能。首先&#xff0c;它能够定…

09-ARM开发板的HelloWorld

在ARM开发板上运行x86_64平台程序 前面在Ubuntu系统编译生成了X86_64平台的HelloWorld程序&#xff0c;通过NFS服务器&#xff0c;尝试在开发板上直接运行。 如图所示&#xff0c;程序无法正常运行&#xff0c;终端提示ARM开发板在执行x86架构&#xff08;Intel或AMD&#xff…