队列(链表实现)概念及相关函数

一. 链表队列

特殊的单链表,只在单链表上进行头删尾插的操作

二. 相关函数

对于队列具体概念不太清楚的同学可以参考

顺序表实现的数据结构队列
由顺序表实现的队列程序结构相对来说比较简单,可以巩固一下基础

链表定义的队列结构

#define Datatype char   // 队列存储数据的类型

// 队列的节点
typedef struct LinkNode {
    Datatype data;
    struct LinkNode* next;
}LinkNode;

// 队首队尾指针
typedef struct LinkQueue {
    LinkNode* head;
    LinkNode* tail;
}LinkQueue;

LinkQueue.h

#pragma once
// 链表实现的队列,后进先出
#include <stdlib.h>
#include <errno.h>
#include <stddef.h>

#define Datatype char


typedef struct LinkNode {
    Datatype data;
    struct LinkNode* next;
}LinkNode;

typedef struct LinkQueue {
    LinkNode* head;
    LinkNode* tail;
}LinkQueue;

// 初始化队列
void LinkQueueInit(LinkQueue* queue);

// 销毁队列
void LinkQueueDestroy(LinkQueue* queue);

// 入队列,尾插
int LinkQueuePush(LinkQueue* queue, Datatype value);

// 出队列,头删
int LinkQueuePop(LinkQueue* queue);

// 取队首元素
int LinkQueueTop(LinkQueue* queue, Datatype* value);

LinkQueue.c

#include "LinkQueue.h"

// 创建节点
LinkNode* Creat(Datatype value) {
    LinkNode* node = malloc(sizeof(LinkNode));
    node->data = value;
    node->next = NULL;
    return node;
}
// 销毁节点
void Destroy(LinkNode* node) {
    // 非法输入
    if(node == NULL) {
        perror("Creat");
        return;
    }
    free(node);
}

// 初始化队列
void LinkQueueInit(LinkQueue* queue) {
    // 非法输入
    if(queue == NULL) {
        perror("Init");
        return;
    }
    queue->head = NULL;
    queue->tail = NULL;
}

// 销毁队列
void LinkQueueDestroy(LinkQueue* queue) {
    // 非法输入
    if(queue == NULL) {
        perror("Destroy");
        return;
    }
    // 销毁创建的链表节点
    LinkNode* cur = queue->head;
    while(cur != NULL) {
        LinkNode* tmp = cur;
        cur = cur->next;
        Destroy(tmp);
    }

    // 销毁链表
    queue->head = NULL;
    queue->tail = NULL;
}

// 入队列,尾插
int LinkQueuePush(LinkQueue* queue, Datatype value) {
    // 非法输入
    if(queue == NULL) {
        perror("Push");
        return;
    }
    // 空链表
    if(queue->head == NULL) {
        queue->head = queue->tail = Creat(value);
        return 1;
    }
    // 创建新节点
    LinkNode* new_node = Creat(value);
    queue->tail->next = new_node;
    queue->tail = new_node;
    return 1;
}

// 出队列,头删
// LinkQueue->node == NULL 代表空链表
int LinkQueuePop(LinkQueue* queue) {
    // 非法输入
    if(queue == NULL) {
        perror("Pop");
        return 0;
    }
    // 空链表
    if(queue->head == NULL) {
        return 0;
    }
    // 一个节点
    if(queue->head == queue->tail) {
        // 销毁节点
        Destroy(queue->head);
        queue->head = queue->tail = NULL;
        return 1;
    }
    LinkNode* tmp = queue->head;
    queue->head = queue->head->next;
    Destroy(tmp);
}

// 取队首元素
int LinkQueueTop(LinkQueue* queue, Datatype* value) {
    // 非法输入
    if(queue == NULL) {
        perror("Top");
        return 0;
    }
    // 空队列
    if(queue->head == NULL) {
        return 0;
    }
    *value = queue->tail->data;
    return 1;

}



/* ***************************************************
   *********************  test  **********************
 * ***************************************************/
#if 1
#include <stdio.h>

#define FUNCTION() printf("\n================ %s ===============\n", __FUNCTION__)


// 队列打印
void print(LinkQueue queue, const char* msg) {
    printf("%s\n", msg);

    // 非法输入
    if(queue.head == NULL) {
        perror("printf");
        return;
    }

    LinkNode* cur = queue.head;
    while(cur != queue.tail) {
        printf("%c\n", cur->data);
        cur = cur->next;
    }
    printf("%c\n", cur->data);
}


// 入队列测试
void TestPush() {
    FUNCTION();
    LinkQueue queue;
    LinkQueueInit(&queue);

    LinkQueuePush(&queue, 'a');
    LinkQueuePush(&queue, 'b');
    LinkQueuePush(&queue, 'c');
    LinkQueuePush(&queue, 'd');
    print(queue, "入队列");
}

// 出队列测试
void TestPop() {
    FUNCTION();
    LinkQueue queue;
    LinkQueueInit(&queue);

    LinkQueuePush(&queue, 'a');
    LinkQueuePush(&queue, 'b');
    LinkQueuePush(&queue, 'c');
    LinkQueuePush(&queue, 'd');
    print(queue, "入队列");

    LinkQueuePop(&queue);
    print(queue, "出队列一个");
    LinkQueuePop(&queue);
    print(queue, "出队列两个");
    LinkQueuePop(&queue);
    print(queue, "出队列三个");
    LinkQueuePop(&queue);
    print(queue, "出队列四个");
    LinkQueuePop(&queue);
    print(queue, "空队列队列");
}

// 获取队首元素测试
void TestTop() {
    FUNCTION();
    LinkQueue queue;
    LinkQueueInit(&queue);

    LinkQueuePush(&queue, 'a');
    LinkQueuePush(&queue, 'b');
    LinkQueuePush(&queue, 'c');
    print(queue, "入队列");

    Datatype value;
    int ret = LinkQueueTop(&queue, &value);
    printf("ret is %d, top is %c\n", ret, value);
    ret = 0;

    // 获取已销毁队列队首元素
    LinkQueueDestroy(&queue);
    ret = LinkQueueTop(&queue, &value);
    printf("ret is %d, top is %c\n", ret, value);

}


int main() {
    TestPush();
    TestPop();
    TestTop();

    return 0;
}
#endif
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值