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

做外贸阿里巴巴有哪些网站徐州百度推广

做外贸阿里巴巴有哪些网站,徐州百度推广,中卫网架钢结构,临海高端营销型网站建设地址队列的概念 队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 一端进另一端出 也就是可以做到,先…

队列的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头

一端进另一端出

也就是可以做到,先进先出

队列的使用场景

队列的经典应用就是保持公平性

比如:抽号机

生产者消费者模型,先来先出去,多线程的话就可能涉及到一个锁的概念

广度优先遍历(概念)

直接好友:好友

间接好友:好友的好友

可以采取队列的方式推荐

队列如何实现

数组的无法实现的因为需要一边进一边出,所以一般是单链表实现队列

同时单链表也会更加省空间

队列的实现 

创建文件

首先我们需要知道单链表实现队列的时候,我们需要有头节点和尾结点,以及链表的实际的个数,所以我们不能在结构体里面创建那麽多结构体,所以我们采取结构体的嵌套

创建栈的结构

// 链式结构:表示队列 
typedef struct QListNode
{QDataType _data;struct QListNode* _next;
}QNode;
// 队列的结构 (因为队列是先进先出,后进后出,也就是和栈是相反的,此时会尾进头出,所以我们需要更新尾部和头部节点)
// (把头结点,尾结点,链表的实际的大小放里面,这样不需要每次使用的时候进行循环找尾,我们只需要每次更新尾结点就可以)
typedef struct Queue
{QNode* _phead;//头节点QNode* _ptail;//尾结点int size;
}Queue;

这段代码定义了两个结构体,QNodeQueue,分别用于表示队列中的节点和整个队列。下面是对每个部分的详细解释:

  1. QNode 结构体:这个结构体表示队列中的单个节点。

    • _data:这是 QNode 结构体中的一个成员变量,用来存储节点中的数据。QDataType 是数据类型的别名,它应该在相关的头文件中定义,代表节点存储的数据类型。
    • _next:这是一个指向 QNode 类型的指针,用来指向同一队列中的下一个节点。如果 _next 为 NULL,表示这是队列中的最后一个节点。
  2. Queue 结构体:这个结构体表示整个队列。

    • _phead:这是一个指向 QNode 类型的指针,用来指向队列的头节点。队列的头节点是最早被加入的节点,也是下一个将要被移除的节点。
    • _ptail:这是一个指向 QNode 类型的指针,用来指向队列的尾节点。队列的尾节点是最后被加入的节点,它用于在添加新元素时更新队列。
    • size:这是一个整数类型的变量,用来存储队列中当前的元素数量。

在队列的链式表示中,不需要像顺序表示(使用数组)那样进行动态内存分配和缩容。链式结构自然地允许队列的动态增长和缩减,因为每个节点独立维护其后继节点的指针。

队列的基本操作包括:

  • 入队(Enqueue):在队尾添加一个新节点。
  • 出队(Dequeue):移除队头的节点,并返回其数据。
  • 查看队头(Peek/Front):返回队头节点的数据但不移除它。
  • 检查队列是否为空(IsEmpty):检查队列的头节点是否为 NULL

初始化与销毁队列

// 初始化队列 
void QueueInit(Queue* ps)
{ps->_phead = NULL;ps->_ptail = NULL;ps->size = 0;
}
// 销毁队列 
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->_phead;while (cur){//存下下一个节点的地址,不会出现找空的情况QNode* next = cur->_next;free(cur);cur =next;}
}
  1. QueueInit 函数

    • 这个函数接收一个指向 Queue 结构体的指针 ps
    • ps->_phead = NULL;:将队列的头节点指针设置为 NULL。这表示队列初始化时是空的,没有任何元素。
    • ps->_ptail = NULL;:将队列的尾节点指针也设置为 NULL。由于队列是空的,头尾节点都不存在。
    • ps->size = 0;:设置队列中元素的数量为0。
  2. QueueDestroy 函数

    • 这个函数同样接收一个指向 Queue 结构体的指针 ps
    • assert(ps);:使用 assert 宏来确保传入的 ps 不是 NULL。如果 ps 是 NULLassert 将触发断言失败,这有助于避免对空指针的无效操作。
    • QNode* cur = ps->_phead;:声明一个 QNode 类型的指针 cur 并初始化为队列的头节点。
    • while (cur):使用 while 循环来遍历队列,直到 cur 为 NULL,即队列中的所有节点都被处理完毕。
    • QNode* next = cur->_next;:在释放当前节点之前,先保存下一个节点的地址,以便在释放当前节点后能够继续遍历队列。
    • free(cur);:使用 free 函数释放当前节点 cur 所占用的内存。
    • cur = next;:将 cur 更新为下一个节点,继续循环直到所有节点都被释放。
    • 循环结束后,队列中的所有节点都被释放,此时队列被销毁。

队尾入队列 

// 队尾入队列 
void QueuePush(Queue* ps, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("QueuePush:newnode:error:");exit(1);}//把需要插入的数值插入到节点里面newnode->_next = NULL;newnode->_data = x;// ps->_phead == ps->_ptail 的结果确实是 true,这表明队列中只有一个元素(头尾相接)。// 但是,通常情况下,我们不会使用 ps->_phead == ps->_ptail // 来检查队列中是否只有一个元素。相反,我们通常会使用 ps->size == 1 或者 ps->_phead != NULL && ps->_ptail != NULL // 来检查队列中是否只有一个元素。//插入节点 第一个节点,这里的判断是不能写成ps->_phead ==ps->_ptail;因为都是空指针不能进行比较//ps->_phead == NULLif (ps->size == 0){ps->_phead = ps->_ptail = newnode;}else{//尾插节点ps->_ptail->_next = newnode;ps->_ptail= newnode;}ps->size++;
}

这段代码定义了一个名为 QueuePush 的函数,用于在队列的尾部添加一个新的元素。

  1. void QueuePush(Queue* ps, QDataType x):函数定义开始,QueuePush 接收一个指向 Queue 结构体的指针 ps 和一个要入队的新数据 x

  2. QNode* newnode = (QNode*)malloc(sizeof(QNode));:使用 malloc 函数为新节点分配内存。newnode 是指向新分配内存的指针。

  3. if (newnode == NULL):检查 malloc 是否成功分配了内存。如果 newnodeNULL,表示内存分配失败。

  4. perror("QueuePush:newnode:error:");:如果内存分配失败,使用 perror 函数输出错误信息。

  5. exit(1);:如果内存分配失败,调用 exit 函数以非零状态码退出程序。

  6. newnode->_next = NULL;:将新节点的 _next 指针设置为 NULL。这是新节点的尾部标识,表示在新节点之后没有更多的节点。

  7. newnode->_data = x;:将新数据 x 存储在新节点的 _data 成员中。

  8. if (ps->size == 0):检查队列是否为空(即队列中的元素数量为0)。

  9. ps->_phead = ps->_ptail = newnode;:如果是空队列,那么新节点同时是头节点和尾节点。因此,将头节点和尾节点指针都指向 newnode

  10. else:如果队列不是空的,执行以下操作:

    • ps->_ptail->_next = newnode;:将当前尾节点的 _next 指针指向新节点,从而将新节点添加到队列的末尾。
    • ps->_ptail = newnode;:更新尾节点指针,使其指向新节点。
  11. ps->size++;:队列中元素的数量增加1。

这段代码实现了队列的尾部入队操作。它首先检查队列是否为空,然后相应地将新节点添加到队列的末尾,并更新尾节点指针和队列的元素数量。如果内存分配失败,程序将输出错误信息并退出。

队头出队列 

// 队头出队列 
void QueuePop(Queue* ps)
{assert(ps && ps->size);// 改变头结点ps->_phead = ps->_phead->_next;ps->size--;
}

这段代码定义了一个名为 QueuePop 的函数,其目的是从队列头部移除一个元素。

  1. #include"Queue.h":这行代码应该位于文件的顶部,用于引入包含 Queue 结构体和 QNode 结构体定义以及 QDataType 类型定义的头文件。

  2. void QueuePop(Queue* ps):函数定义开始,QueuePop 接收一个指向 Queue 结构体的指针 ps 作为参数。

  3. assert(ps && ps->size);assert 是一个宏,用于在运行时测试一个条件是否为真。如果条件为假,则 assert 将产生一个断言失败,通常会导致程序异常终止。在这里,它用于确保传入的队列指针 ps 不是 NULL,并且队列中至少有一个元素(即 ps->size 大于0)。

  4. ps->_phead = ps->_phead->_next;:这行代码将队列的头节点指针 _phead 更新为指向下一个节点,从而移除当前队列头部的节点。由于队列是先进先出(FIFO)的数据结构,队头节点是将要被移除的节点。

  5. ps->size--;:队列中元素的数量减少1。

这段代码实现了队列的头部出队操作。它首先通过 assert 检查队列是否非空,然后将头节点指针移动到下一个节点,以此出队操作,最后更新队列的元素数量。

获取队列头部元素

// 获取队列头部元素 
QDataType QueueFront(Queue* ps)
{assert(ps && ps->size);return ps->_phead->_data;
}
  1. QueueFront 函数

    • 这个函数接收一个指向 Queue 结构体的指针 ps
    • assert(ps && ps->size);:使用 assert 宏确保传入的队列指针 ps 不是 NULL,并且队列中至少有一个元素(即 ps->size 大于0)。
    • return ps->_phead->_data;:返回队列头部节点的 _data 成员。由于队列是先进先出(FIFO)的数据结构,队头节点的 _data 成员包含了最早被加入的元素的值。

获取队列队尾元素 

// 获取队列队尾元素 
QDataType QueueBack(Queue* ps)
{assert(ps && ps->size);return ps->_ptail->_data;
}
  1. QueueBack 函数

    • 这个函数同样接收一个指向 Queue 结构体的指针 ps
    • assert(ps && ps->size);:使用 assert 宏确保传入的队列指针 ps 不是 NULL,并且队列中至少有一个元素。
    • return ps->_ptail->_data;:返回队列尾部节点的 _data 成员。在链式队列中,尾部节点是最后一个被加入的节点,其 _data 成员包含了最近一个被加入的元素的值。

获取队列中有效元素个数

// 获取队列中有效元素个数 
int QueueSize(Queue* ps)
{return ps->size;
}
  1. QueueSize 函数

    • 这个函数接收一个指向 Queue 结构体的指针 ps
    • return ps->size;:返回队列中有效元素的个数,即 size 成员的值。

检测队列是否为空,如果为空返回非零结果,如果非空返回0 

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* ps)
{assert(ps);return ps->size == 0;
}

QueueEmpty 函数

  • 这个函数接收一个指向 Queue 结构体的指针 ps
  • assert(ps);:使用 assert 宏确保传入的队列指针 ps 不是 NULL
  • return ps->size == 0;:检查队列是否为空。如果 size 成员的值等于0,则表示队列为空,函数返回非零值(在C语言中,非零值被视为“真”),否则返回0(“假”)

 队列代码的总结 

Queue.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode
{QDataType _data;struct QListNode* _next;
}QNode;
// 队列的结构 (因为队列是先进先出,后进后出,也就是和栈是相反的,此时会尾进头出,所以我们需要更新尾部和头部节点)
// (把头结点,尾结点,链表的实际的大小放里面,这样不需要每次使用的时候进行循环找尾,我们只需要每次更新尾结点就可以)
typedef struct Queue
{QNode* _phead;//头节点QNode* _ptail;//尾结点int size;
}Queue;
// 这里采取一级指针进行实现代码逻辑,如果不创建队列的结构,我们就需要采取二级指针
// 初始化队列 
void QueueInit(Queue* ps);
// 销毁队列 
void QueueDestroy(Queue* ps);
// 队尾入队列 
void QueuePush(Queue* ps, QDataType data);
// 队头出队列 
void QueuePop(Queue* ps);
// 获取队列头部元素 
QDataType QueueFront(Queue* ps);
// 获取队列队尾元素 
QDataType QueueBack(Queue* ps);
// 获取队列中有效元素个数 
int QueueSize(Queue* ps);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* ps);

Queue.c

#include"Queue.h"
// 初始化队列 
void QueueInit(Queue* ps)
{ps->_phead = NULL;ps->_ptail = NULL;ps->size = 0;
}
// 销毁队列 
void QueueDestroy(Queue* ps)
{assert(ps);QNode* cur = ps->_phead;while (cur){//存下下一个节点的地址,不会出现找空的情况QNode* next = cur->_next;free(cur);cur =next;}
}
// 队尾入队列 
void QueuePush(Queue* ps, QDataType x)
{QNode* newnode = (QNode*)malloc(sizeof(QNode));if (newnode == NULL){perror("QueuePush:newnode:error:");exit(1);}//把需要插入的数值插入到节点里面newnode->_next = NULL;newnode->_data = x;// ps->_phead == ps->_ptail 的结果确实是 true,这表明队列中只有一个元素(头尾相接)。// 但是,通常情况下,我们不会使用 ps->_phead == ps->_ptail // 来检查队列中是否只有一个元素。相反,我们通常会使用 ps->size == 1 或者 ps->_phead != NULL && ps->_ptail != NULL // 来检查队列中是否只有一个元素。//插入节点 第一个节点,这里的判断是不能写成ps->_phead ==ps->_ptail;因为都是空指针不能进行比较//ps->_phead == NULLif (ps->size == 0){ps->_phead = ps->_ptail = newnode;}else{//尾插节点ps->_ptail->_next = newnode;ps->_ptail= newnode;}ps->size++;
}
// 队头出队列 
void QueuePop(Queue* ps)
{assert(ps && ps->size);// 改变头结点ps->_phead = ps->_phead->_next;ps->size--;
}
// 获取队列头部元素 
QDataType QueueFront(Queue* ps)
{assert(ps && ps->size);return ps->_phead->_data;
}
// 获取队列队尾元素 
QDataType QueueBack(Queue* ps)
{assert(ps && ps->size);return ps->_ptail->_data;
}
// 获取队列中有效元素个数 
int QueueSize(Queue* ps)
{return ps->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* ps)
{assert(ps);return ps->size == 0;
}
http://www.dinnco.com/news/84242.html

相关文章:

  • 在网站制作意见征集是怎么做的扬州seo博客
  • 什么电商平台免费开店深圳抖音seo
  • 怎么知道网站用wordpress淘宝指数
  • 网站域名可以自己做吗黄冈便宜的网站推广怎么做
  • 网站做视频怎么赚钱的查图百度识图
  • 网站建设应解决的问题郑州网络优化实力乐云seo
  • 哪个网站可以学做包包佛山seo网站排名
  • 设计师专用网站快速建站工具
  • 知名做网站价格有没有免费的写文案的软件
  • 怎么做qq钓鱼网站吗推广运营怎么做
  • 建一个优化网站多少钱seoyoon
  • 数据分析网站企业网站制作费用
  • 房子如何上网站做民宿360收录查询
  • 简单易做的网站在线刷关键词网站排名
  • 做姓氏图的网站广州百度seo
  • 怎样注册一个网站做电商百度站长统计工具
  • 山东大连网站优化与seo
  • 皖icp合肥网站开发公司如何用模板建站
  • 网站开发开票交税额网站功能优化
  • 微网站建设加盟网络推广主要是做什么工作
  • 做视频赚钱的好网站网络推广页面
  • 库尔勒网站建设哪家专业武汉网站提升排名
  • 梅州哪里做网站地推公司排名
  • 招聘网站做沙龙seo技术公司
  • 做网站优化有必要网络营销品牌推广公司
  • 樟木头网站推广百度推广怎么收费标准
  • 湖州网站制作百度推广有哪些推广方式
  • 怎样做网站备份小学生简短小新闻十条
  • 吕梁做网站的公司免费网站注册免费创建网站
  • 阳春做网站公司淘宝关键词搜索排行榜