【C数据结构】队列_Queue

目录

队列_Queue

【1】队列的概念及结构

【2】节点队列的实现

【2.1】队列的各个接口

【2.2】队列的初始化

【2.3】队列栈的释放

【2.4】队尾入队列

【2.5】队头出队列

【2.6】获取队列头部元素

【2.7】获取队列尾部元素

【2.8】获取队列中有效元素个数

【2.9】检测队列是否为空


队列_Queue

【1】队列的概念及结构

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

入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 。

栈符合后进先出(First In First Out )

【C数据结构】队列_Queue_第1张图片

【2】节点队列的实现

        队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

【C数据结构】队列_Queue_第2张图片

【2.1】队列的各个接口

#pragma once
#include 
#include 
#include 
#include 


// 栈数据结构定义 ///
/* 栈数据结构 */
typedef int QDataType;
typedef struct QListNode {
    QDataType _data;
    struct QListNode *_nextNode;
}QNode;

typedef struct Queue {
    QNode* _head;
    QNode* _tail;
    size_t _size;
}Q;


// 栈常用接口定义 ///
/* 队列:初始化 */ 
void QueueInit(Q* q);

/* 队列:销毁 */
void QueueDestroy(Q* q);

/* 队列:尾插 */
void QueuePush(Q* q, QDataType val);

/* 队列:头出 */
void QueuePop(Q* q);

/* 队列:获取头部数据 */
QDataType QueueFront(Q* q);

/* 队列:获取尾部数据 */
QDataType QueueBack(Q* q);

/* 队列:获取队列有效元素个数 */
size_t QueueSize(Q* q);

/* 队列:检查是否为空栈 */
bool QueueEmpty(Q* q);

【2.2】队列的初始化

/* 队列:初始化 */
void QueueInit(Q* q) {
    // 断言
    assert(q);

    // 初始化
    q->_head = q->_tail = NULL;
    q->_size = 0;
}

【2.3】队列栈的释放

/* 队列:销毁 */
void QueueDestroy(Q* q) {
    // 断言
    assert(q);

    // 遍历释放
    QNode* pCur = q->_head;
    while (pCur != NULL) {
        QNode* pDel = pCur;
        pCur = pCur->_nextNode;

        free(pDel); pDel = NULL;
    }

    // 初始化
    q->_head = q->_tail = NULL;
    q->_size = 0;
}

【2.4】队尾入队列

  • 入队列动画演示

【C数据结构】队列_Queue_第3张图片 

  • 入队会出现两种情况

【C数据结构】队列_Queue_第4张图片

 

/* 队列:尾插 */
void QueuePush(Q* q, QDataType val) {
    // 断言
    assert(q);

    // 开辟节点
    QNode* newNode = (QNode*)malloc(sizeof(QNode));
    // 开辟失败
    if (newNode == NULL) {
        perror("malloc fail!");
        exit(-1);
    }
    // 开辟成功
    else
    {
        newNode->_data = val;
        newNode->_nextNode = NULL;
    }

    // 插入数据
    // 链表为空
    if (q->_tail == NULL) {
        q->_head = q->_tail = newNode;
    }
    // 链表不为空
    else
    {
        q->_tail->_nextNode = newNode;
        q->_tail = q->_tail->_nextNode;
    }
    // 记录数据个数
    q->_size++;
}

【2.5】队头出队列

【C数据结构】队列_Queue_第5张图片

/* 队列:头出 */
void QueuePop(Q* q) {
    // 断言
    assert(q);

    // 链表剩余最后一个节点数据
    if (q->_head->_nextNode == NULL) {
        free(q->_head);  
        q->_head = q->_tail = NULL;
    }
    // 链表有很多数据
    else
    {
        QNode* pDel = q->_head;
        q->_head = q->_head->_nextNode;
        free(pDel); pDel = NULL;
    }
}

【2.6】获取队列头部元素

/* 队列:获取头部数据 */
QDataType QueueFront(Q* q) {
    // 断言
    assert(q);
    // 检测是否是空
    assert(!QueueEmpty(q));
    return q->_head->_data;
}

【2.7】获取队列尾部元素

/* 队列:获取尾部数据 */
QDataType QueueBack(Q* q) {
    // 断言
    assert(q);
    // 检测是否是空
    assert(!QueueEmpty(q));
    return q->_tail->_data;
}

【2.8】获取队列中有效元素个数

/* 队列:获取队列有效元素个数 */
size_t QueueSize(Q* q) {
    // 断言
    assert(q);
    return q->_size;
}

【2.9】检测队列是否为空

/* 队列:检查是否为空栈 */
bool QueueEmpty(Q* q) {
    // 断言
    assert(q);
    return q->_head == NULL && q->_tail == NULL;
}

你可能感兴趣的:(C,数据结构,c语言,数据结构)