数据结构3.1-简单队列

队列

何为

队列和栈相反,遗址中先进先出的线性表,他的入队与出队分别在队列的俩头,即只允许一端插入元素,另一端删除元素,与现实中的队列一样

队列示意图:

入队端(队尾)                    出队端(队头)
     ↓                              ↓
┌─────┬─────┬─────┬─────┬─────┬─────┐
│  A  │  B  │  C  │  D  │  E  │     │
├─────┼─────┼─────┼─────┼─────┼─────┤
← 插入元素方向              删除元素 →
     (rear)                        (front)

队列的操作有:入队出队取队头元素判队空/满
此处我们依旧使用C语言示例队列的增删查改

操作

1.初始化

在这里我们先定义队列节点结构体

typedef struct QNode{
    int data;
    struct QNode *next;
} QNode, *QueuePtr;

其中,我们定义了队列结构体的别名QNode,同时定义了指向结构体的指针别名QueuePtr

typedef struct{
    QueuePtr front;//对头指针域
    QueuePtr rear;//队尾指针域
} *LinkQueue;

由于我们要处理队头队尾,所以我们在这里定义了对头和队尾的指针

void InitQueue(LinkQueue Q){ 
    Q->front = Q->rear = NULL;
    printf("队列初始化成功!");
}

随后我们将队头和队尾都初始化为NULL,同时输出初始化成功

2.入队

void append(LinkQueue Q, int e){
    QNode *p = (QNode *)malloc(sizeof(QNode));//申请空间
    p->data = e;//把数据存储到数据域
    p->next = NULL;//该节点的下一节点置空指向NULL
    Q->rear->next = p;//队尾指针域的next指向新节点
    Q->rear = p;
}

队列的入队操作,我们首先申请一个节点,然后把数据存储到数据域,同时将下一节点置空,然后队尾指针域的next指向新节点,最后将队尾指针域指向新节点

3.出队

// 出队
void pop(LinkQueue Q, int *e){
    //判对空
    if(Q == NULL || Q->front == NULL){
        printf("队列为空!n");
    }
    QNode *p = Q->front;     // 保存当前队头节点的地址
    *e = p->data;            // 将要删除节点的数据赋值给输出参数e
    Q->front = p->next;      // 将队头指针指向下一个节点,实现队头出队

    // 如果删除的是最后一个节点(即删除后队列变空),则rear也需要置为NULL
    if(Q->front == NULL) { 
        Q->rear = NULL;    
    }

    free(p);                 // 释放被删除节点占用的内存空间
    printf("元素 %d 出队成功n", *e);  // 输出出队成功的提示信息
}

在出队的操作中,我们首先判对空,当队伍不为空时我们进行下一步操作
先定义一个*p指针指向对头,随后保存下对头的数据,然后队头指针指向下一个节点,如果删除的是最后一个节点,则队尾指针也置为NULL
最后释放要删除的节点
注意:在删除时,我们务必要先判断是否队空,否则会出问题!!!

4.取队头

void getHead(LinkQueue Q, int *e){
    //判队空
    if(Q == NULL || Q->front == NULL){
        printf("队列为空!n");
    }
    *e = Q->front->data;
    printf("队头元素为:%dn", *e);
}

5.遍历

void traverse(LinkQueue Q){
    if(Q == NULL || Q->front == NULL){
        printf("队列为空!n");
    }
    for(QNode *p = Q->front; p != NULL; p = p->next){
        printf("%d ", p->data);
        printf("n");
    }
}

在for循环遍历中,我们从队头开始,通过指针域依次遍历,直至遍历至队尾指向NULL

写到这里的时候突然想到我不应该用int来定义然后return 0/return 1的,因为这里是一个个方法代表一个操作,处理都是在方法中的,所以返回值应该返回void

销毁队列

void destroy(LinkQueue Q) {
    if(Q == NULL) {
        printf("队列指针为空,无需销毁n");
        return;
    }

    // 循环删除所有节点
    while(Q->front != NULL) {
        QNode *temp = Q->front;      // 保存当前队头节点
        Q->front = Q->front->next;   // 移动队头指针到下一个节点
        free(temp);                  // 释放当前节点内存
    }

    // 队列为空时,rear也应该为NULL
    Q->rear = NULL;

    printf("队列销毁成功!n");
}

总结

综上便是简单队列的一些简单的增删查改的一些操作了,但是还有一个循环队列和其他几个,可能要搁置一下,因为目前鄙人对队列还有一些不太清楚的,所以就先到这里了,后面会尽快补上的
完整代码可以在同文件夹下的./queque1.c中找到,博客会把代码附在评论区
感谢支持!

评论

  1. 博主
    1 月前
    2026-1-10 12:26:12
    #include<stdio.h>
    #include<stdlib.h>
    
    //初始化
    typedef struct QNode{
        int data;
        struct QNode *next;
    } QNode, *QueuePtr;
    
    typedef struct{
        QueuePtr front;//对头指针域
        QueuePtr rear;//队尾指针域
    } *LinkQueue;
    
    void InitQueue(LinkQueue Q){ 
        Q->front = Q->rear = NULL;
        printf("队列初始化成功!");
    }
    
    //入队
    void append(LinkQueue Q, int e){
        if(Q->front == NULL){//
            printf("队列为空!");
        }
        QNode *p = (QNode *)malloc(sizeof(QNode));//申请空间
        p->data = e;//把数据存储到数据域
        p->next = NULL;//该节点的下一节点置空指向NULL
        Q->rear->next = p;//队尾指针域的next指向新节点
        Q->rear = p;
    }
    
    //出队
    // 出队
    void pop(LinkQueue Q, int *e){
        // 检查队列是否为空或队列指针是否有效,如果为空则无法进行出队操作
        if(Q == NULL || Q->front == NULL){
            printf("队列为空!\n");
        }
    
        QNode *p = Q->front;     // 保存当前队头节点的地址,准备删除
        *e = p->data;            // 将要删除节点的数据赋值给输出参数e
        Q->front = p->next;      // 将队头指针指向下一个节点,实现队头出队
    
        // 如果删除的是最后一个节点(即删除后队列变空),则rear也需要置为NULL
        if(Q->front == NULL) {   // 判断删除后队列是否为空
            Q->rear = NULL;      // 重要:同时将队尾指针也设为NULL,保持一致性
        }
    
        free(p);                 // 释放被删除节点占用的内存空间
        printf("元素 %d 出队成功\n", *e);  // 输出出队成功的提示信息
    }
    
    //取对头
    void getHead(LinkQueue Q, int *e){
        //判队空
        if(Q == NULL || Q->front == NULL){
            printf("队列为空!\n");
        }
        *e = Q->front->data;
        printf("队头元素为:%d\n", *e);
    }
    
    //遍历
    void traverse(LinkQueue Q){
        if(Q == NULL || Q->front == NULL){
            printf("队列为空!\n");
        }
        for(QNode *p = Q->front; p != NULL; p = p->next){
            printf("%d ", p->data);
            printf("\n");
        }
    }
    
    //销毁
    // 销毁队列
    void destroy(LinkQueue Q) {
        if(Q == NULL) {
            printf("队列指针为空,无需销毁\n");
            return;
        }
    
        // 循环删除所有节点
        while(Q->front != NULL) {
            QNode *temp = Q->front;      // 保存当前队头节点
            Q->front = Q->front->next;   // 移动队头指针到下一个节点
            free(temp);                  // 释放当前节点内存
        }
    
        // 队列为空时,rear也应该为NULL
        Q->rear = NULL;
    
        printf("队列销毁成功!\n");
    }

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
皖ICP备2025092305号-1