目录
  • 前言
  • 一. 什么是队列
  • 二. 使用什么来实现栈
  • 三. 队列的实现
    • 3.1头文件
    • 3.2 函数的实现
  • 四.完整代码

    前言

    前一段时间,我们试着用C语言实现了数据结构中的顺序表,单链表,双向循环链表,栈。今天我们再用C语言来实现另一种特殊的线性结构:队列

    一. 什么是队列

    队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(head)进行删除操作,而在表的后端(tail)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

    这个队列就可以理解成我们平时的排队,先进入的先出去,与我们之前实现的先进后出的栈相反。

    二. 使用什么来实现栈

    再把上次的图拿出来,我们看看是用线性表来实现队列,还是链表比较好

    不同点 顺序表 链表
    存储空间上 物理上一定连续 逻辑上连续,但物理上不一定连续
    随机访问 可以直接访问任何元素 必须从头节点开始往后寻找
    任意位置插入或删除元素 要搬移其他的元素,效率低。 只需要修改节点的指针指向,效率高
    插入 动态顺序表,当空间不够时需要扩容 无容量概念,需要就申请,不用就释放
    应用场景 元素高效存储,并且需要频繁访问 需要在任意位置插入或者删除频繁

    综合上表来看,我觉得链表较为方便,原因如下:

    1.队列有多少元素不确定,链表可以做到需要就申请,不用就释放,较为方便

    2.队列是先进先出,顺序固定,不需要随机访问。

    三. 队列的实现

    3.1头文件

    1.包含的标准库

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <assert.h>
    

    2.定义结构体

    typedef int QDateType;//队列存储数据类型
    
    typedef struct QueueNode //队列元素节点
    {
    	QDateType val;
    	struct QueueNode* next;
    }QueueNode;
    
    typedef	struct Queue //队列
    {
    	QueueNode* head;
    	QueueNode* tail;
    }Queue;
    

    3.函数声明

    void QueueInti(Queue* pq);
    // 队列初始化
    void QueueDestory(Queue* pq);
    // 队列的销毁
    void QueuePush(Queue* pq, QDateType x);
    // 入队
    void QueuePop(Queue* pq);
    // 出队
    QDateType QueueFront(Queue* pq);
    // 取出队首元素
    int QueueSize(Queue* pq);
    // 求队列的长度
    bool QueueEmpty(Queue* pq);
    // 判断队是否为空
    

    3.2 函数的实现

    1.队列的初始化

    将头尾置为空指针即可。

    void QueueInti(Queue* pq)
    {
        assert(pq); //防止pq为空指针
        pq->head = pq->tail = NULL;
    }
    

    2.队列的销毁

    遍历队列元素,然后将每一个元素释放。

    void QueueDestory(Queue* pq)
    {
        assert(pq); //防止pq为空指针
        QueueNode* cur = pq->head;
        while (cur)
        {
            QueueNode* next = cur->next;
            free(cur);
            cur = next;
        }
        pq->tail = pq->head = NULL;
    }
    

    C语言实现队列的示例详解

    3.入队

    对于入队,我们首先需要去开辟一个新的节点来存储数据,然后将这个节点加入到tail后即可。此时我们就要分别考虑。

    1.如果为空队列,那么我们不仅要改变tail,还要改变head的值

    2.如果不为空队列,只用改变tail即可。

    void QueuePush(Queue* pq, QDateType x)
    {
    	assert(pq); //防止pq为空指针
    
    	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    	if (NULL == newNode)
    	{
    		printf("malloc error\n");
    		exit(-1);
    	}
    	newNode->val = x;
    	newNode->next = NULL;//开辟一个新节点存储数据
    
    	if (pq->tail == NULL)//判断是否为空队列
    	{
    		assert(pq->head == NULL);
    		pq->head = pq->tail = newNode;
    	}
    	else
    	{
    		pq->tail->next = newNode;
    		pq->tail = newNode;
    	}
    }
    

    C语言实现队列的示例详解

    4.出队

    对于出队,我们同样需要考虑两种情况

    • 队列为空,改变head的同时改变tail
    • 队列不为空,改变head即可。
    void QueuePop(Queue* pq)
    {
        assert(pq);//防止pq为空指针
        assert(pq->head && pq->tail); //防止队列为空队列
        if (pq->head->next == NULL)
        {
            free(pq->head);
            pq->head = pq->tail = NULL;
        }
        else
        {
            QueueNode* next = pq->head->next;
            free(pq->head);
            pq->head = next;
        }
    }
    

    C语言实现队列的示例详解

    5. 取出队首元素

    没啥说的,直接访问头节点取出即可

    QDateType QueueFront(Queue* pq)
    {
        assert(pq);//防止pq为空指针
        assert(pq->head && pq->tail); //防止队列为空队列
    
        return pq->head->val;
    }
    

    6.判断是否为空队列

    我们只需要判断头指针是否为NULL,如果是则为空

    bool QueueEmpty(Queue* pq)
    {
        assert(pq);
    
        return pq->head == NULL;
    }
    

    7. 求队伍长度

    创建一个变量,遍历队伍求长度。

    int QueueSize(Queue* pq)
    {
        assert(pq);
        QueueNode* cur = pq->head;
        int count = 0;
        while (cur)
        {
            cur = cur->next;
            count++;
        }
        return count;
    }
    

    四.完整代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <assert.h>
    
    typedef int QDateType;
    
    typedef struct QueueNode
    {
    	QDateType val;
    	struct QueueNode* next;
    }QueueNode;
    
    typedef	struct Queue
    {
    	QueueNode* head;
    	QueueNode* tail;
    }Queue;
    
    void QueueInti(Queue* pq)
    {
    	assert(pq);
    	pq->head = pq->tail = NULL;
    }
    
    void QueueDestory(Queue* pq)
    {
    	assert(pq);
    	QueueNode* cur = pq->head;
    	while (cur)
    	{
    		QueueNode* next = cur->next;
    		free(cur);
    		cur = next;
    	}
    	pq->tail = pq->head = NULL;
    }
    
    void QueuePush(Queue* pq, QDateType x)
    {
    	assert(pq);
    
    	QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));
    	if (NULL == newNode)
    	{
    		printf("malloc error\n");
    		exit(-1);
    	}
    	newNode->val = x;
    	newNode->next = NULL;
    
    	if (pq->tail == NULL)
    	{
    		assert(pq->head == NULL);
    		pq->head = pq->tail = newNode;
    	}
    	else
    	{
    		pq->tail->next = newNode;
    		pq->tail = newNode;
    	}
    
    }
    
    void QueuePop(Queue* pq)
    {
    	assert(pq);
    	assert(pq->head && pq->tail);
    	if (pq->head->next == NULL)
    	{
    		free(pq->head);
    		pq->head = pq->tail = NULL;
    	}
    	else
    	{
    		QueueNode* next = pq->head->next;
    		free(pq->head);
    		pq->head = next;
    	}
    }
    
    bool QueueEmpty(Queue* pq)
    {
    	assert(pq);
    
    	return pq->head == NULL;
    }
    
    QDateType QueueFront(Queue* pq)
    {
    	assert(pq);
    	assert(pq->head);
    
    	return pq->head->val;
    }
    
    int QueueSize(Queue* pq)
    {
    	assert(pq);
    	QueueNode* cur = pq->head;
    	int count = 0;
    	while (cur)
    	{
    		cur = cur->next;
    		count++;
    	}
    	return count;
    }
    
    

    以上就是C语言实现队列的示例详解的详细内容,更多关于C语言 队列的资料请关注其它相关文章!

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。