c语言的数据结构:队列

1.队列存在的实现方式及其存在意义

1.1为什么队列使用单链表实现更好

  1. 动态内存分配:链表在C语言中通常使用动态内存分配,这意味着可以在运行时根据需要动态地添加或删除节点。这对于实现一个动态大小的队列非常有用,因为队列的大小可以在运行时变化。相比之下,数组的大小通常是固定的,需要在编译时确定,这可能会限制队列的灵活性。
  2. 插入和删除效率:在链表中,插入和删除操作的时间复杂度为O(1)(在已知位置的情况下)。这意味着在链表的头部或尾部添加或删除节点非常高效。由于队列是一种先入先出(FIFO)的数据结构,我们通常在队列的尾部添加元素(入队),并在头部删除元素(出队)。因此,使用链表实现队列可以充分利用其高效的插入和删除操作。
  3. 空间效率:链表只存储节点本身的数据和指向下一个节点的指针,不需要像数组那样预留一定的空间。这使得链表在存储大量数据时更为空间高效.

1.2 队列存在的意义

无论是栈,队列,抑或是树,它们基本都是由顺序表,链表这些基本的元素构成的,并且人们将栈,队列等一些数据结构发明出来也是为了根据人类的需求解决人类的一些问题,举一个例子,医院叫号排队,为了防止有些人乱插队从而引起的不必要的纠纷,于是以数据结构队列为基本原理开发出有关排队就医的系统 

2.有关队列的一些基本操作如何使用c语言代码将其具现化

2.1如何写一个队列的结点

typedef int QDataType;
typedef struct QueueNode
{
    int val;
    struct QueueNode* next;
}QNode;

typedef struct Queue
{
    QNode* phead; // 指向队列头部的指针  
    QNode* ptail;  // 指向队列尾部的指针  
    int size;
} Queue;

如果只是写一个队列的结点

然后在之后的对队列的操作每次都去再设置一个头指针和尾指针如果我们需要去找队列的尾结点,那么就需要尾指针每次都从头开始去遍历整个链表的结点,但是这样做的话时间复杂度便可以来到O(n),是不合情的

所以我们在最初设置队列的结点相关基础信息的时候就连带着将它的头指针和尾指针一并设置好.

设置两个结点指针phead和ptail,例如我们每次进行一次尾插操作,就让ptail指向新的尾结点,如此一来,ptail便一直指向尾结点,每当我们需要取去寻找尾结点是,可以直接使用ptail,就不需要再去从头开始遍历了.

2.2队列的初始化操作

void QueueInit(Queue* pq)
{
    assert(pq);//pq是指向结构体的指针
    pq->phead = NULL;
    pq->ptail = NULL;
    pq->size = 0;
}

2.3队列的销毁操作

//销毁操作
void QueueDestroy(Queue* pq)
{
    assert(pq);
    QNode* cur = pq->phead;//从头开始销毁,和出队一样
    while (cur != NULL)
    {
        QNode* nexttemp = cur->next;
        free(cur);
        cur = nexttemp;
    }

    pq->phead = pq->ptail = NULL;
    pq->size = 0;
}

 QNode* nexttemp = cur->next;

这一步的意思是为了保证在将cur目前所指向的结点删除以后还可以定位到原被删除结点的下一个结点,所以事先将下一个结点cur->next用创建的临时变量nexttemp保存起来,待目前结点被删除以后,cur又快速指向下一个结点cur->next结点.

2.4入队操作

//入队
void QueuePush(Queue* pq,QDataType x)
{
    assert(pq);
    QNode* newnode = (QNode*)malloc(sizeof(QNode));
    if (newnode == NULL)
    {
        perror("malloc fail");
        return;
    }
    newnode->val = x;
    newnode->next = NULL;
    if (pq->ptail = NULL)//啥都没有
    {
        pq->ptail = pq->phead = newnode;

    }
    else//本来就有结点
    {
        pq->phead->next = newnode;
        pq->ptail = newnode;
    }
    pq->size++;
}

2.5出队操作

//出队
void QueuePop(Queue* pq)
{
    assert(pq);
    //暴力检查
    //至少要有一个结点才可以进行销毁操作

    assert(pq->phead!=NULL);
     
    if (pq->phead->next == NULL)
    {
        free(pq->phead);
        pq->phead = pq->ptail = NULL;
    }
    else
    {
        QNode* nexttemp = pq->phead->next;
        free(pq->phead);
        pq->phead = nexttemp;
    }
    pq->size--;
}

2.6取头操作

//取头
QDataType  QueueFront(Queue* pq)
{
    assert(pq);
    //要有首结点才可以进行取头操作
    assert(pq->phead != NULL);
    return pq->phead->val;
}

2.7取尾操作

//取尾
QDataType QueueBack(Queue* pq)
{
    assert(pq);
    //要有尾结点才可以进行取尾操作
    assert(pq->ptail != NULL);
    return pq->ptail->val;
}

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

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

相关文章

外链工具,热门的外链工具

在网络推广和搜索引擎优化中,外链工具是提升网站排名和曝光度的关键。本文将介绍一些外链工具,以及它们的作用和用途。 外链工具有哪些? 147SEO工具: 147SEO工具是一款提升网站收录的外链工具,用户可以通过147SEO工具…

antvX6 - Vue自定义节点,并实现多种画布操作,拖拽、缩放、连线、双击、检索等等

一、 首先 antv x6 分为两个版本 低版本和高版本 我这里是使用的2.0版本 并且搭配了相关插件 例如:画布的图形变换、地图等 个人推荐 2.0版本,高版本配置多,可使用相关插件多,但是文档描述小,仍在更新, 低…

JavaWeb之 Web概述

目录 前言1.1 Web和 JavaWeb的概念1.2 JavaWeb技术栈1.2.1 B/S架构1.2.2 静态资源1.2.3 动态资源1.2.4 数据库1.2.5 HTTP协议1.2.6 Web服务器 1.3 JavaWeb 学习内容 前言 博主将用 CSDN 记录 Java 后端开发学习之路上的经验,并将自己整理的编程经验和知识分享出来&a…

yolo目标检测实战

该博客主要介绍了: 1. 如何制作yolo目标检测数据集 2.如何在自己的数据集上训练yolo 3.训练好后的模型如何进行推理 1.数据标注 关于数据如何标注,请查看这篇博文 2.数据集目录结构 重点关注红框内部的结构 images: 图片目录 images/train: 训练集…

Zookeeper学习1:概述、安装、应用场景、集群配置

文章目录 概述安装LinuxWindows 配置参数集群参考配置文件配置步骤流程启动 概述 Zookeeper: 为分布式框架组件提供协调服务的中间件 【类似:文件系统通知机制】 负责存储上下层应用关系的数据以及接收观察者注册监听,一旦观察查关心的数据发…

npm与包

包 包的概念 Node.js中的第三方模块又叫做包。包的来源 由第三方个人或团队开发出来的,免费提供给所有人使用。为什么需要包 由于Node.js内置模块仅提供了一些底层的API,导致在基于内置模块进行项目开发时,效率很低。包是基于内置模块封装出…

在idea中用模板骨架初始创建maven管理的web项目时没有src有关的目录的解决方案

一.问题如下 二.解决方法 首先关闭当前项目,接着修改全局设置,重新创建项目 在VM Options中添加"-DarchetypeCataloginternal",点击ok保存 点击创建,如果创建成功没报错且有src,就ok了。 当然如果出现以下…

Avalonia学习(二十八)-OpenGL

Avalonia已经继承了opengl,详细的大家可以自己查阅。Avalonia里面启用opengl继承OpenGlControlBase类就可以了。有三个方法。分别是初始化、绘制、释放。 这里把官方源码的例子扒出来给大家看一下。源码在我以前发布的单组件里面。地址在前面的界面总结博文里面。 …

vue cesium加载点与定位到指定位置

vue cesium定位到指定位置 window.viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(point.longDeg, point.latDeg, 6500000), orientation: {heading: 6.2079384332084935, roll: 0.00031509431759868534, pitch: -1.535}, duration: 3})vue cesium加载点 …

[技巧]Arcgis之图斑四至范围批量计算

ArcGIS图层(点、线、面三类图形)四至范围计算 例外一篇介绍:[技巧]Arcgis之图斑四至点批量计算 说明:如下图画出来的框(范围标记不是很准) ,图斑的x最大和x最小,y最大,…

css实现居中

基础代码&#xff1a; <div class"box"><div class"content"></div> </div> css实现居中的几种方式&#xff1a; 1、flex布局&#xff08;水平垂直&#xff09; .box {width: 200px;height: 200px;background-color: pink;disp…

如何利用Flutter来写后端 服务端应用

前言 Flutter是谷歌推出的一款跨平台开发框架&#xff0c;现在属于此领域star最多的框架&#xff0c;其被广泛应用于构建前台界面&#xff0c;但或许很少人知道&#xff0c;他也可以写后端应用。 本文主角 flutter非常著名的getx库推出的get server jonataslaw/get_server:…