链式队列和顺序队列

首先来看一下百度百科关于队列的介绍:

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

队列满足先进先出(FIFO)的原则,我们可以用链表的尾插头删模拟队列,还可以用顺序表实现循环队列。
下面介绍一下循环栈:
这里写图片描述

seqqueue.h

#include<stdio.h>
#include<stddef.h>

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

//设置最大数量 4,这样设置是为了在后面的测试中方便模拟达到最大元素的状态
#define SeqQueueMaxSize 4
typedef char SeqQueueType;
typedef struct SeqQueue{
    SeqQueueType data[SeqQueueMaxSize];
    size_t head;
    size_t tail;
    size_t size;
} SeqQueue;

//初始化函数
void SeqQueueInit(SeqQueue* q);
//入队列函数
void SeqQueuePush(SeqQueue* q,SeqQueueType value);
//出队列函数
void SeqQueuePop(SeqQueue* q);
//打印函数
void SeqQuquqPrint(SeqQueue* q,const char* msg);
//取对手元素
int SeqQueueFront(SeqQueue* q,SeqQueueType* value);

seqqueue.c

#include"seqqueue.h"

void SeqQueueInit(SeqQueue* q){
    if(q == NULL){
        return;
    }
    q->tail = 0;
    q->head = 0;
    q->size = 0;
    return;
}

void SeqQueuePush(SeqQueue* q,SeqQueueType value){
    if(q == NULL){
        return;
    }
    if(q->size >= SeqQueueMaxSize){
        return;
    }
    q->data[q->tail++] = value;
    if(q->tail >= SeqQueueMaxSize){
    //如果队列的tail号下标达到最大值,下一个元素在数组的0号元素插入
        q->tail = 0;
    }
    q->size++;
}

void SeqQueuePop(SeqQueue* q){
    if(q == NULL){
        return;
    }
    if(q->size == 0){
        return;
    }
    q->head++;
    if(q->head >= SeqQueueMaxSize){
        q->head = 0;
    }
    q->size--;
}
//打印函数
void SeqQuquqPrint(SeqQueue* q,const char* msg){
    if(q == NULL){
        return;
    }
    printf("[ %s ]:\n",msg);
    int i = q->tail - 1;
    int count = q->size - 1;
    打印tail开始的count个元素
    while(count--){
        if(i >= 0){
            printf("%c->",q->data[i--]);
        }else{
            i = SeqQueueMaxSize - 1;
            printf("%c->",q->data[i--]);
        }
    }
    printf("%c\n",q->data[q->head]);
    return;
}

//取队首元素,这里的value是输出型参数
int SeqQueueFront(SeqQueue* q,SeqQueueType* value){
    if(q == NULL){
        return 0;
    }
    if(q->size == 0){
        return 0;
    }
    *value = q->data[q->head];
    return 1;
}

main.c

#include"seqqueue.h"

void TestSeqQueuePush(){
    TestType;
    SeqQueue q;
    SeqQueueInit(&q);
    SeqQueuePush(&q,'a');
    SeqQueuePush(&q,'b');
    SeqQueuePush(&q,'c');
    SeqQueuePush(&q,'d');
   // SeqQueuePush(&q,'e');
    SeqQuquqPrint(&q,"abcde入队列");
    SeqQueuePop(&q);
    SeqQuquqPrint(&q,"a出队列");
    SeqQueuePop(&q);
    SeqQuquqPrint(&q,"b出队列");
    SeqQueuePush(&q,'e');
    SeqQuquqPrint(&q,"e入队列");
    return;
}

void TestSeqQueueFront(){
    TestType;
    SeqQueueType value;
    SeqQueue q;
    SeqQueueInit(&q);
    SeqQueuePush(&q,'a');
    SeqQueuePush(&q,'b');
    SeqQueuePush(&q,'c');
    SeqQueuePush(&q,'d');
    int ret = SeqQueueFront(&q,&value);
    printf("expect: 1 , actual:%d\n",ret);
    printf("expect: a , actual:%c\n",value);
    SeqQueuePop(&q);
    SeqQueuePop(&q);
    SeqQueuePush(&q,'e');
    SeqQuquqPrint(&q,"ab出队列,e入队列");
    ret = SeqQueueFront(&q,&value);
    printf("expect: 1 , actual:%d\n",ret);
    printf("expect: c , actual:%c\n",value);
    return;
}

int main(){
    TestSeqQueuePush();
    TestSeqQueueFront();
    return 0;
}

上面就是用顺序表模拟队列的实现过程。

下面来介绍一下,链式队列
linkqueue.c

#pragma once
#include<stdio.h>
#include<stddef.h>
#include<stdlib.h>

#define TestType printf("\n################################## %s #################################\n",__FUNCTION__)
#define LinkQueueType char

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

typedef struct LinkQueue{
    struct LinkNode* head;
    struct LinkNode* tail;
} LinkQueue;
//初始化函数
void LinkQueueInit(LinkQueue* q);
//入队列函数
void LinkQueuePush(LinkQueue* q,LinkQueueType value);
//打印函数
void LinkQueuePrint(LinkQueue* q,const char* msg);
//出队列函数
void LinkQueuePop(LinkQueue* q);
//取队首元素
int LinkQueueFront(LinkQueue* q,LinkQueueType* value);

linkqueue.c

#include"linkqueue.h"

void LinkQueueInit(LinkQueue* q){
    if(q == NULL){
        return;
    }
    q->head = NULL;
    q->tail = NULL;
    return;
}

LinkNode* LinkQueueCreateNode(LinkQueueType value){
    LinkNode* new_node = (LinkNode*)malloc(sizeof(LinkNode));
    if(new_node == 0){
        return NULL;
    }
    new_node->next = NULL;
    new_node->data = value;
    return new_node;
}

void DestroyNode(LinkNode* to_delete){
    if(to_delete == NULL){
        return;
    }
    free(to_delete);
    return;
}

void LinkQueuePush(LinkQueue* q,LinkQueueType value){
    if(q == NULL){
        return;
    }
    LinkNode* new_node = LinkQueueCreateNode(value);
    if(q->head == NULL){
        q->head = new_node;
        q->tail = new_node;
        return;
    }
    q->tail->next = new_node;
    q->tail = q->tail->next;
    return;
}

void LinkQueuePrint(LinkQueue* q,const char* msg){
    if(q == NULL){
        return;
    }
    printf("[ %s ]:\n",msg);
    LinkNode* cur = q->head;
    while(cur != NULL){
        printf("[%c][%p]<-",cur->data,cur);
        cur = cur->next;
    }
    printf("NULL\n\n");
    return;
}

void LinkQueuePop(LinkQueue* q){
    if(q == NULL){
        return;
    }
    if(q->head == NULL){
        return;
    }
    LinkNode* temp = q->head;
    q->head = q->head->next;
    DestroyNode(temp);
    return;
}

int LinkQueueFront(LinkQueue* q,LinkQueueType* value){
    if(q == NULL){
        return 0;
    }
    *value = q->head->data;
    return 1;
}

以上就是关于链式队列的介绍。
由于我的能力有限,上面的介绍可能有不妥或者Bug,欢迎发邮件到我的邮箱(Cyrus_wen@163.com)批评指正!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值