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

机械行业做网站天津seo推广方法

机械行业做网站,天津seo推广方法,wordpress整站ssl,做传销一般是不是有网站目录 第一性原理:为什么需要链表? 设计链表的节点和队列结构 1. 积木:节点 (Node) 2. 蓝图:队列的结构 (Queue) 第2步:队列的诞生与状态检查 创建一个空队列 判断队列是否为空 第3步:核心操作 (入队…

目录

第一性原理:为什么需要链表?

设计链表的节点和队列结构

1. 积木:节点 (Node)

2. 蓝图:队列的结构 (Queue)

第2步:队列的诞生与状态检查

创建一个空队列

 判断队列是否为空

第3步:核心操作 (入队与出队)

入队 (Enqueue)

出队 (Dequeue)

第4步:善后工作 (销毁队列)


我们再次从第一性原理出发,承接上文,这次我们来探讨如何用链表来实现一个队列。我们同样会一步步分析,发现问题,并逐步完善代码。

数据结构:队列(Queue)与循环队列(Circular Queue)-CSDN博客

第一性原理:为什么需要链表?

我们已经知道,基于数组的循环队列有一个天生的“缺陷”:容量固定

在创建队列时,我们必须预先指定其最大容量。如果业务需求变化,元素数量可能远超预期,队列就会“溢出”;如果预估过大,则会浪费内存。

如何解决这个问题?我们需要一个“用多少,拿多少”的动态结构。这正是链表的拿手好戏。

我们需要一个数据结构,能够高效地(时间复杂度 O(1))在头部移除元素,并在尾部添加元素。


设计链表的节点和队列结构

链表是由一个个“节点”串联起来的。所以,我们首先需要设计这个最基本的“积木”。

1. 积木:节点 (Node)

一个节点需要包含什么信息?

  1. 数据本身 (int data)

  2. 指向下一个节点的指针 (struct Node* next),这是把它“链接”起来的关键。

【代码实现 1:节点结构体定义】

#include <stdio.h>
#include <stdlib.h>// 链表节点,是构成我们队列的基本单元
typedef struct Node {int data;struct Node* next;
} Node;

2. 蓝图:队列的结构 (Queue)

如何用链表来组织,才能满足 O(1) 的头删和尾增?

如果我们有一个指针指向链表的头节点,我们称之为 front

那么删除头节点的操作就是把 front 指向 front->next,这本身是 O(1) 的。

  • 从头部删除 (Dequeue):

  • 在尾部添加 (Enqueue):

如果我们只有一个 front 指针,为了找到尾部,我们必须从头遍历整个链表,时间复杂度是 O(N),这太慢了,不符合我们的要求。

为了实现 O(1) 的尾部添加,我们必须始终保留一个直接指向尾节点的指针。我们称之为 rear

因此,我们的队列结构需要两个指针:一个指向头,一个指向尾。

【代码实现 2:链式队列结构体定义】

// 链式队列的蓝图
typedef struct {Node* front; // 指向队头节点Node* rear;  // 指向队尾节点
} LinkedQueue;

这个结构比数组实现更简洁,因为它不需要关心容量和下标。


第2步:队列的诞生与状态检查

创建一个空队列

一个空的链式队列是什么样的?它没有任何节点。因此,它的 frontrear 指针都应该指向 NULL

【代码实现 3:创建队列函数】

// 功能:创建一个空的链式队列
LinkedQueue* createLinkedQueue() {// 1. 为队列结构体本身分配内存LinkedQueue* q = (LinkedQueue*)malloc(sizeof(LinkedQueue));if (!q) {perror("Failed to allocate memory for LinkedQueue");return NULL;}// 2. 初始化,空队列的头尾指针都为 NULLq->front = NULL;q->rear = NULL;return q;
}

 判断队列是否为空

这比数组实现简单得多。只要 front 指针是 NULL,队列就是空的。

【代码实现 4:判空函数】

// 功能:判断队列是否为空
int isLinkedQueueEmpty(LinkedQueue* q) {// 如果 front 为 NULL,队列必为空return q->front == NULL;
}

注意:链式队列理论上没有“满”的状态(除非整个计算机的内存耗尽),所以我们不需要 isFull 函数。


第3步:核心操作 (入队与出队)

这是链式队列最关键的部分,包含了一些必须小心处理的“边界情况”。

入队 (Enqueue)

向队尾添加一个元素 value

  1. 创建新节点:无论如何,我们都需要先根据 value 创建一个新的节点。

  2. 处理边界情况:如果当前队列是空的 (frontNULL),那么这个新节点既是队头也是队尾。所以 frontrear 都应该指向这个新节点。

  3. 处理通用情况:如果队列不为空,我们只需做两件事:

a. 让当前的队尾节点(q->rear)的 next 指针指向新节点。

b. 更新队尾指针 q->rear,让它指向这个新节点。

【代码实现 5:入队函数】

// 功能:将元素 value 加入队尾
void enqueueLinked(LinkedQueue* q, int value) {// 1. 无论如何,都先创建新节点Node* newNode = (Node*)malloc(sizeof(Node));if (!newNode) {perror("Failed to allocate memory for new node");return;}newNode->data = value;newNode->next = NULL; // 新节点总是被加在最后,所以它的 next 永远是 NULL// 2. 处理队列为空的特殊情况if (isLinkedQueueEmpty(q)) {q->front = newNode;q->rear = newNode;} else {// 3. 通用情况:将新节点链接到队尾,并更新队尾指针q->rear->next = newNode;q->rear = newNode;}
}

出队 (Dequeue)

从队头取出一个元素。

  1. 检查:队列是否为空?空则无法出队。

  2. 获取数据:要返回的数据在 front 指针指向的节点里。

  3. 移动指针:将 front 指针移动到下一个节点 (q->front = q->front->next)。

  4. 释放内存:原来的头节点已经“游离”出队列了,必须用 free 释放它的内存。

  5. 处理最关键的边界情况

如果出队的是队列中最后一个元素,那么在移动 front 指针后,front 会变为 NULL

此时队列变空,但 rear 指针还指向刚刚被释放的那个无效内存地址!

这非常危险。我们必须在这种情况下,同时将 rear 指针也设置为 NULL

【代码实现 6:出队函数】

// 功能:从队头取出一个元素,并通过指针 pValue 返回
int dequeueLinked(LinkedQueue* q, int* pValue) {// 1. 检查是否为空if (isLinkedQueueEmpty(q)) {printf("出队失败:队列为空。\n");return 0; // 失败}// 为了稍后释放,临时保存旧的头节点Node* temp = q->front;// 2. 获取数据*pValue = temp->data;// 3. 移动 front 指针到下一个节点q->front = q->front->next;// 4. 处理最关键的边界:如果出队后队列变空了if (q->front == NULL) {// 必须同时更新 rear 指针,否则 rear 会成为一个危险的“野指针”q->rear = NULL;}// 5. 释放旧的头节点内存free(temp);return 1; // 成功
}

第4步:善后工作 (销毁队列)

销毁整个队列意味着要释放所有节点的内存,以及队列结构体本身的内存。

最简单的方法是利用我们已经写好的 dequeueLinked 函数。

【代码实现 7:销毁函数】

// 功能:销毁整个队列,释放所有内存
void destroyLinkedQueue(LinkedQueue* q) {int dummyValue; // 用于接收出队元素,我们不关心它的值// 不断地从队列中取出元素,直到队列为空// dequeueLinked 函数会自动释放每个节点的内存while (!isLinkedQueueEmpty(q)) {dequeueLinked(q, &dummyValue);}// 最后,释放队列结构体本身的内存free(q);
}

通过以上步骤,我们从链表的基本特性出发,推导出了需要 frontrear 两个指针来满足性能要求,并细致地处理了入队和出队时的各种边界情况,最终构建了一个功能完整、健壮的链式队列。

http://www.dtcms.com/a/400712.html

相关文章:

  • 大模型剪枝系列——LoRA-Pruning
  • 免费活动策划方案的网站微购电商小程序
  • 做办公室的网站郑州论坛官网
  • 高校教资--高等心理学
  • 网站报错解析做网站赚钱的QQ群
  • 网络编程完结整理
  • 上海建设摩托车官方网站抖音seo公司
  • 红安建设局官方网站金华手机建站模板
  • 企业网站推广费用开发软件都有哪些
  • 织梦mip网站改造wordpress二次元简约主题
  • 企业网站怎么建微商城网站建设代理商
  • 网站建设工作人员有哪些职责大同工程建设信息网
  • 一家专门做原型的网站国建设网站
  • jsp做的婚恋网站如何让网站自适应手机
  • 陕西交通建设集团西商分公司网站北京星光灿烂影视有限公司
  • 网站上传ftp返利淘网站怎么做
  • 网站上传源码后怎么弄厦门网站推广步骤机构
  • 网站建设-易速通科技厦门某某公司网站
  • 公司网站建设制作商济南seo推广效果好
  • Linux文件fd-重定向-缓冲区
  • SpringAI Alibaba 集成与简单使用
  • 网站规划与建设规划书wordpress如何添加目录菜单
  • 常州市网站建设设计深圳国外网站制作公司
  • 万网建站流程网络规划设计师属于高级职称吗
  • wordpress建站小百科网站手机模板和pc模板要分开做
  • 网站设计建设公司1.2婚庆网站建设的目的
  • wordpress插件系统大连百度推广seo
  • 张家港做网站的公司用公司注册公司需要什么资料
  • 网站制作替我们购买域名wordpress docker镜像
  • 化肥厂的网站摸板wordpress修改登陆地址后缀