【数据结构】顺序队列与链式队列

顺序队列与链式队列

1.队列的基本概念

队列是一种逻辑结构,是一种特殊的线性表

  • 只能在固定的两端操作线性表

只要满足上述条件,那么这种特殊的线性表就会呈现一种"先进先出"的逻辑,这种逻辑就被称为队列。

由于约定了只能在线性表固定的两端进行操作,于是给队列这种特殊的线性表的插入删除,起个特殊的名称:

  • 队头:可以删除节点的一端
  • 队尾:可以插入节点的一端
  • 入队:将节点插入到队尾之后,函数名通常为enQueue()
  • 出队:将队头节点从队列中剔除,函数名通常为outQueue()
  • 取队头:取得队头元素,但不出队,函数名通常为front()

1.顺序存储的队列:循环队列

c 复制代码
#include <stdio.h>
#include <stdlib.h>

#define QUEUE_SIZE 10

typedef struct sq_queue
{
    int data[QUEUE_SIZE];
    int tail;
}sq_queue_t;

// 
sq_queue_t *sq_queue_init(void)
{
    sq_queue_t *my_sq_queue = malloc(sizeof(sq_queue_t));
    
    (my_sq_queue->tail) = -1;
    return my_sq_queue;
}

// 入队
int en_queue(int new_data, sq_queue_t *sq_queue)
{
    // 判断队列是否满了
    if (sq_queue->tail > QUEUE_SIZE - 1)
    {
        printf("队列已满!\n");
        return -1;
    }
    
    (sq_queue->tail)++;
    sq_queue->data[sq_queue->tail] = new_data;
    return 0;
}

// 出队
int out_queue(sq_queue_t *sq_queue)
{
    int i;
    if (sq_queue->tail < 0)
    {
        printf("队列已空!\n");
        return -1;
    }
    int temp = sq_queue->data[0];
    for (i = 0; i < sq_queue->tail; i++)
    { 
        sq_queue->data[i] = sq_queue->data[i+1];
    }
    (sq_queue->tail)--;
    return temp;
}

int main(int argc, char const *argv[])
{
    int i;
    sq_queue_t *my_sq_queue = sq_queue_init();
    if (!my_sq_queue)
    {
        printf("[main] init fail\n");
        return -1;
    }

    for (i = 0; i < 12; i++)
    {
        en_queue(i, my_sq_queue);
    }

    for (i = 0; i < 12; i++)
    {
        printf("出队数据:%d\n", out_queue(my_sq_queue));
    }
    
    return 0;
}

3.链式存储的队列:链式队列

c 复制代码
#include <stdio.h>
#include <stdlib.h>

typedef struct list_queue
{
    int data;
    struct list_queue *tail;
    struct list_queue *next;
}list_queue_t;

// 初始化链式队列, 定义结构体变量
list_queue_t *list_queue_init(void)
{
    list_queue_t *queue_head = malloc(sizeof(list_queue_t));
    queue_head->next = NULL;
    queue_head->tail = queue_head; // 对尾指针指向头节点,每次插入新的节点需要更新队尾指针

    return queue_head;
}

// 入队--尾插
int in_queue(int new_data, list_queue_t *queue)
{
    list_queue_t *new_node = malloc(sizeof(list_queue_t));
    // 初始化数据域
    new_node->data = new_data;
    new_node->next = NULL;
    new_node->tail = NULL;
    // 把新的节点插入到队尾后面
    queue->tail->next = new_node; 
    // 更新队尾---指向新的节点
    queue->tail = new_node;

    return 0;
}

// 出队--把头节点的下一个节点删除,返回该节点的数据
int out_queue(list_queue_t *queue)
{
    // 判断队列是否为空
    if (!queue->next)
    {
        printf("队列已空!\n");
        return -1;
    }
    
    // 定义指针p指向待删除的节点--也就是头节点的下一个节点
    list_queue_t *p = queue->next;
    // 备份待删除节点的数据
    int temp = p->data;
    // 将头节点的next指针指向待删除节点的下一个节点--删除队首
    queue->next = p->next;

    p->next = NULL;
    free(p);

    return temp;
}

#define IN_QUEUE_NUM 5
int main(int argc, char const *argv[])
{
    unsigned char i;
    list_queue_t *head_queue = list_queue_init();
    for (i = 0; i < IN_QUEUE_NUM; i++)
    {
        in_queue(i, head_queue);
    }
    
    for (i = 0; i < IN_QUEUE_NUM + 1; i++)
    {
        printf("出队的数据:%d\n", out_queue(head_queue));
    }
    

    return 0;
}

/*
执行结果:
    出队的数据:0
    出队的数据:1
    出队的数据:2
    出队的数据:3
    出队的数据:4
    队列已空!
    出队的数据:-1

*/
相关推荐
孤廖6 分钟前
吃透 C++ 栈和队列:stack/queue/priority_queue 用法 + 模拟 + STL 标准实现对比
java·开发语言·数据结构·c++·人工智能·深度学习·算法
豆沙沙包?1 小时前
2025年--Lc197-077. 排序链表(链表,尾插法)--Java版
java·数据结构·链表
江公望1 小时前
Qt的QT_QPA_EGLFS_INTEGRATION环境变量浅解
linux·qt·qml
杨福瑞2 小时前
C语言数据结构:算法复杂度(2)
c语言·开发语言·数据结构
YuCaiH2 小时前
网络编程的基础知识
linux·笔记·嵌入式·网络通信
Siren_dream2 小时前
在VMware上运行Linux(我选择的是Ubuntu)
linux·运维·ubuntu
是店小二呀2 小时前
远程办公自由:rdesktop+cpolar让Windows桌面随身而行
windows
☆璇2 小时前
【Linux】Socket编程UDP
linux·网络·udp
涤生z2 小时前
list.
开发语言·数据结构·c++·学习·算法·list
嵌入式小能手3 小时前
飞凌嵌入式ElfBoard-Vim编辑器之Vim常用操作命令
linux·编辑器·vim