队列(数组实现和链表实现)

来源:互联网 发布:超级玛丽 java 编辑:程序博客网 时间:2024/06/13 10:58

1.概念:具有一定操作约束的线性表
2.特点:(1)只能在一端插入(入队),另一端删除(出队)。
(2).先进先出。
3.存储实现方式:数组、链表。
4.基本操作:
1.数组实现(循环数组):
注意:(1)、普通的顺序存储的数组用来实现队列时,存在一个问题:当rear(记录队尾的变量)到达maxsize-1时,不能确定队列是否满,因为前面可能删除了一些元素(front(记录对头的变量)可能已经增加了),所以用循环数组来实现队列的操作
(2)、对于循环数组,无论是空队列还是满队列,front与rear都相等,所以,引入了一个变量size来记录队列中元素的个数。
基本操作:
(1)、队列结构体定义:

typedef struct Queue{    int data[maxsize];    int front;    int rear;    int size;}Q;

(2)、建立空队列:

Q *makeEmpty(Q *q)//建立空队列 {    q->size = 0;    q->front = -1;    q->rear = -1;    return q;}

(3)、判断队列是否空,是否满:

int Isempty(Q *q)//判断队列是否为空 {    return (q->size) == 0;}int Isfull(Q *q)//判断队列是否满 {    return q->size == maxsize;} 

(4)、入队列和出队列:

void AddQ(Q *q,int num)//入队列 {    if(Isfull(q))//判断队列是否满     {        printf("队列满!\n");        return ;    }    else    (q->size)++;    q->data[(++(q->rear)%maxsize)] = num;    //先将rear+1,再对maxsize取余得到下标     return ;}int deleteQ(Q *q)//出队列{    if(Isempty(q))    {        printf("队列空!\n");        return 0;    }    else    {        (q->size)--;        q->front = (++(q->front)%maxsize);        return q->data[q->front];//front+1为要删除的元素的下标     }}

(5)、数组实现队列的完整代码:

#include <stdio.h>#define maxsize 10#include <stdlib.h>typedef struct Queue{    int data[maxsize];    int front;    int rear;    int size;}Q;int Isempty(Q *q)//判断队列是否为空 {    return (q->size) == 0;}int Isfull(Q *q)//判断队列是否满 {    return q->size == maxsize; } Q *makeEmpty(Q *q)//建立空队列 {    q->size = 0;    q->front = -1;    q->rear = -1;    return q;}void AddQ(Q *q,int num)//入队列 {    if(Isfull(q))//判断队列是否满     {        printf("队列满!\n");        return ;    }    else    (q->size)++;    q->data[(++(q->rear)%maxsize)] = num;//先将rear+1,再对maxsize取余得到下标     return ;}int deleteQ(Q *q){    if(Isempty(q))    {        printf("队列空!\n");        return 0;    }    else    {        (q->size)--;        q->front = (++(q->front)%maxsize);        return q->data[q->front];//front+1为要删除的元素的下标     }}int main(){    Q *q;    q = (Q*)malloc(sizeof(Q));//动态申请内存     q = makeEmpty(q);    int n = Isempty(q);    printf("x%d\t",n);    for(int i = 0;i<2;i++)    {        AddQ(q,i);    }    n = Isempty(q);    printf("x%d\t",n);      for(int i = 0;i < 2;i++)    {        int temp = deleteQ(q);        printf("%d\t",temp);    }    free(q);    return 0;    } 

输出结果:
这里写图片描述
2.链表实现队列:
注意:由于链表的尾不能进行删除操作,所以front指向链表的头,rear指向链表的尾。
(1)、 结构体的定义:

typedef struct Node{    int data;    struct Node *next;}Qnode;typedef struct {    Qnode *front;//指向链表头结点     Qnode *rear;//指向链表尾结点 }Q;

(2)、核心代码:增添和删除结点信息

void AddQ(Q *q,int num)//增添结点 {    Qnode *p = (Qnode *)malloc(sizeof(Qnode));    p->data = num;    Qnode *temp = q->rear;    if(temp != NULL)//判断队列是否为空     {        temp->next = p;        q->rear = p;        p->next = NULL;    }    else    {        q->front =  p;//若队列为空,将首尾均指向新增结点         q->rear = p;        p->next = NULL;    }} 
int deleteQ(Q *q)//删除结点并返回删除结点的值 {    Qnode *temp;    int term;    if(q->front == NULL)    {        printf("队列空!\n");        return 0;    }    temp = q->front;//保留头结点     if(q->front == q->rear)//若队列只有一个元素     q->front = q->rear = NULL;//将头结点尾结点都设为空     else    q->front = q->front->next;//否则改变头结点    term = temp->data;     free(temp);//释放头结点     return term;//返回头结点的值 }

(3)、完整代码:

#include <stdio.h>#include <stdlib.h>typedef struct Node{    int data;    struct Node *next;}Qnode;typedef struct {    Qnode *front;//指向链表头结点     Qnode *rear;//指向链表尾结点 }Q;int deleteQ(Q *q)//删除结点并返回删除结点的值 {    Qnode *temp;    int term;    if(q->front == NULL)    {        printf("队列空!\n");        return 0;    }    temp = q->front;//保留头结点     if(q->front == q->rear)//若队列只有一个元素     q->front = q->rear = NULL;//将头结点尾结点都设为空     else    q->front = q->front->next;//否则改变头结点    term = temp->data;     free(temp);//释放头结点     return term;//返回头结点的值 }void AddQ(Q *q,int num)//增添结点 {    Qnode *p = (Qnode *)malloc(sizeof(Qnode));    p->data = num;    Qnode *temp = q->rear;    if(temp != NULL)//判断队列是否为空     {        temp->next = p;        q->rear = p;        p->next = NULL;    }    else    {        q->front =  p;//若队列为空,将首尾均指向新增结点         q->rear = p;        p->next = NULL;    }} int main(){    Q *q =(Q *) malloc(sizeof(Q));    q->front = q->rear = NULL;     for(int i = 0;i < 2;i++)    {        AddQ(q,i);    }    for(int i = 0;i<2;i++)    {        int n = deleteQ(q);        printf("%d\t",n);    }    free(q);    return 0;}

运行结果:这里写图片描述

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 兔子身上有胶怎么办 硅胶手机壳脏了怎么办 手机太滑了怎么办 油井套管断了怎么办 一二苯胍过敏怎么办 墨盒托架被卡怎么办 安华花洒调节不了方向怎么办 广联达计价软件打不开怎么办 夏天中午浇花了怎么办 喷壶不喷水了怎么办 防止油锅溢油怎么办 公寓消防喷头失灵怎么办 喷头管子裂了怎么办 露台有燃气管道怎么办 布防报警器响了怎么办 汽车报警器老响怎么办 铝框箱子扣不上怎么办 旅行箱 卡扣坏了怎么办 天然气火力不旺怎么办 内螺纹坏了怎么办 ppr管内丝松动了怎么办 点开微信链接被扣钱了怎么办 下水道往外渗水怎么办 小区下水道堵了怎么办 洗碗下水管堵塞怎么办 小区下水管漏水怎么办 墙内下水道漏水怎么办 暖气回水管漏水怎么办 厨房下水道管子漏水怎么办 硬是堵住马桶了怎么办 请问下水道堵了怎么办 下水道堵实了怎么办 农村下水道堵了怎么办 南京房子水管漏水怎么办 下雨天卫生间屋顶漏水怎么办 打孔打到水管怎么办 卫生间门角渗水怎么办 预埋水管漏水怎么办 下水管漏水慢怎么办 排水管破了漏水怎么办 水管弯头盖漏水怎么办