队列_顺序队列 & 链式队列

队列 (Queue)
队头出,队尾入
操作集合:
(1)QueueInitiate(Q) 初始化队列Q
(2)QueueNotEmpty(Q) 队列Q非空否
(3)QueueAppend(Q,x) 入队列
(4)QueueDelete(Q,d) 出队列
(5)QueueGet(Q,d) 取队头数据元素

顺序队列:

队头是第一个元素的下标,队尾是最后一个元素下标+1(最后空位)
顺序队列假溢出问题:

顺序队列因多次入队和出队操作后出现的有存储空间但不能进行入队操作的溢出。

顺序循环队列的基本原理:
把顺序队列所使用的存储空间构造成一个逻辑上首尾相连的循环队列。当 rear 和 front 达到MaxQueueSize-1 后,再前进一个位置就自动到0。

定义:

typedef struct
{
    ElemType queue[MaxQueueSize];
    int rear;   //队尾
    int front;  //对头
    int count;  //计数器:用于区分空队和满队 
}SequenceQueue;

(1)QueueInitiate(Q) 初始化队列Q

void QueueInitiate(SequenceQueue *Q)
{
    Q->rear = 0;
    Q->count = 0;
    Q->front = 0;
}

(3)QueueAppend(Q,x) 入队列

int QueueAppend(SequenceQueue *Q, ElemType x)
{
    if(Q->count>0 && Q->rear == Q->front)
    {
        printf("队列已满无法插入\n");
        return 0;
    }
    else
    {
        Q->queue[Q->rear] = x;
        //一个小的数跟一个大的数取余会得到自身,两数相等,取余为0 
        Q->rear = (Q->rear + 1) % MaxQueueSize;
        //这种好理解
        /*Q->rear++;
        if(Q->rear == MaxQueueSize) Q->rear = 0;*/
        Q->count++;
        return 1;
    }
} 

(4)QueueDelete(Q,d) 出队列

int QueueDelete(SequenceQueue *Q, ElemType *d)
{
    if(Q->count == 0)
    {
        printf("队列已空无法出队\n");
        return 0;
    }
    else
    {
        *d = Q->queue[Q->front];
        Q->front = (Q->front + 1) % MaxQueueSize;
        Q->count--;
        return 1;
    }
} 

测试代码:输入10个数,输出10个数。

#include<stdio.h>
#include<stdlib.h>
#define MaxQueueSize 50
#define ElemType int
#include "SequenceQueue.h"
void main(void)
{
    int i, x;
    SequenceQueue myQueue;
    QueueInitiate(&myQueue);
    
    for(i = 1; i<=10; i++)
    {
        QueueAppend(&myQueue, i);
    }
    while(myQueue.count != 0)
    {
        QueueDelete(&myQueue, &x);
        printf("%d\n", x);
    }
} 

链式队列:

SingleLinkList 定义队列节点

typedef struct LinkList 
{
    ElemType data;
    struct LinkList *next;
}SingleLinkList;

LinkQueue 定义队列:队头、队尾指针

typedef struct
{
    SingleLinkList *front;
    SingleLinkList *rear;
}LinkQueue;

LinkQueueInit 初始化

void LinkQueueInit(LinkQueue *LQ)
{
    LQ->front = NULL;
    LQ->rear = NULL;
}

LinkQueueNotEmpty 判空

int LinkQueueNotEmpty(LinkQueue LQ)
{
    if(LQ.front == NULL) return 0;
    else return 1;
} 

LinkQueueAppend 入队

int LinkQueueAppend(LinkQueue *LQ, ElemType x)
{
    SingleLinkList *p = (SingleLinkList *)malloc(sizeof(SingleLinkList));
    if(p == NULL)
    {
        printf("内存不足!入队失败");
        return 0;
    }
    p->data = x;
    p->next = NULL;
    if(LQ->rear != NULL)
    {
        LQ->rear->next = p;
        LQ->rear = p;
    }
    if(LQ->front == NULL)//第一次插入 
    {
        LQ->front = p;
        LQ->rear = p;       
    }
    return 1;       
}

LinkQueueOut 出队

int LinkQueueOut(LinkQueue *LQ, ElemType *x) 
{
    if(LQ->front == NULL)
    {
        printf("队空,出队出错!");
        return 0;
    }
    *x = LQ->front->data;
    
    SingleLinkList *p = LQ->front;
    LQ->front= LQ->front->next;//队头往前移 
    free(p);
    
    return 1;
}

GetLinkQueueFront 获取对头元素

int GetLinkQueueFront(LinkQueue LQ, ElemType *x) 
{
    if(LQ.front == NULL)
    {
        printf("队空!");
        return 0;
    }
    *x = LQ.front->data;
    return 1;
}

Destroy 销毁队列

void Destroy(LinkQueue Q) 
{
    SingleLinkList *p, *q;
    p = Q.front;
    while(p != NULL)
    {
        q = p;
        p = p->next;
        free(q);
    }
}

总结:
1、从原来的头指针(head)变成队头(front)队尾(rear)指针;
2、写入数据只能从队尾写入,读取数据只能从队头读取。

测试代码:

#include<stdio.h>
#include<stdlib.h>
#define ElemType int
#include "LinkQueue.h"
void main(void)
{
    LinkQueue Q;
    LinkQueueInit(&Q);//初始化 
    int i, x;
    for(i=0; i<10; i++)
    {
        LinkQueueAppend(&Q, i+1);//入队 
    }
    GetLinkQueueFront(Q, &x);//队头元素 
    printf("%d\n",x);
    while(LinkQueueNotEmpty(Q))//判空 
    {
        LinkQueueOut(&Q, &x);//出队 
        printf("%d ", x);
    }
    Destroy(Q);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • 数据结构 第7讲 循环队列 过了一段时间,小张再也受不了...
    rainchxy阅读 8,974评论 4 16
  • 栈与列队 栈是限定仅在表尾进行插入和删除操作的线性表 队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性...
    Longshihua阅读 1,133评论 0 3
  • 注:不足及错误请指正 +qq1366963396讨论 队列(queue)是只允许在一端进行插入操作,而在另一端进行...
    lxr_阅读 868评论 0 0
  • 本文主要讲解了队列的定义和队列主要功能实现的算法。最后会列举一些队列在程序设计当中常见的应用实例!相信了解了队列对...
    xiaoyouPrince阅读 1,021评论 0 0
  • 自从给自己定一个写点东西的的小目标后 连做梦都是写文章,做总结。 新的生物钟也形成了,4点50时还没到就醒了,难道...
    沙漏的眼泪阅读 110评论 0 1