顺序存储
#ifndef _SEQUEUE_H_
#define _SEQUEUE_H_
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>//bool类型头文件
#include<string.h>
/*************队列的顺序存储****************/
//顺序存储 以数组为存储工具 队列遵循先进先出的规则 即出队的一端为队首
//入队的一端为队尾,类似排队 通过数组为数据存储工具 再分别定义两个变量,分别指向队尾和队首 表示其首尾的当前位置
//两个变量都会随着出队入队的操作 位置后移),导致之前队列虽有存储位置,但后续入队 达到队列的最大值,使得入队操作无法继续进行导致的溢出,这种就是假溢出现象
// (有位置 但放不下去)
//因此往往通过构建一个循环来使得空出的位置得到循环利用 解决假溢出
//通过取模的方式 即在不满队的情况下 队尾到达队列存储的最大值之 前 进行 取模,回到存放之前存放第一个数据的位置
#define MAXSIZE 7 //队列大小
//实际存储 6个数据
typedef int datatype ;
typedef struct sequeue{
datatype data[MAXSIZE];//队列数组
int front;//指向队首的前一个位置
int rear;//指向队尾巴
}seq_queue,*seq_pqueue;
seq_pqueue init_sequeue(void);//队列创建 及初始化
bool insert_sequeue(seq_pqueue q,datatype data);//入队
bool quit_sequeue(seq_pqueue q,datatype *D);//出队
bool is_full_sequeue(seq_pqueue q);//判满
bool is_empty_sequeue(seq_pqueue q);//判空
void show_sequeue(seq_pqueue q);//遍历队列
#endif
#include "sequeue.h"
seq_pqueue init_sequeue(void)//队列创建 及初始化
{
seq_pqueue q = (seq_pqueue)malloc(sizeof(seq_queue));
if(q == NULL)
{
perror("malloc");
exit(-1);
}
q->front = q->rear = MAXSIZE - 1;//初始化让它们指向队尾 (队首的前一个位置就是队尾)这也是空队的条件
return q;
}
bool insert_sequeue(seq_pqueue q,datatype data)//入队
{
if(is_full_sequeue(q))
{
return false;
}
q->rear = (q->rear + 1)%MAXSIZE;//尾巴后移
q->data[q->rear] = data;//放入数据
return true;
}
bool quit_sequeue(seq_pqueue q,datatype *D)//出队
{
if(is_empty_sequeue(q))
{
return false;
}
q->front = (q->front+1)%MAXSIZE;//出队 front 表示队首前一个数 i+1 表示当前数要出队
*D = q->data[q->front];//将这个数放入D中
return true;
}
bool is_full_sequeue(seq_pqueue q)//判满
{
if(q->front == (q->rear+1)%MAXSIZE)//为什么要加1 再进行取模 ?
//因为是空队情况下(初始化) front = rear = MAXSIZE -1
//又因为 满队时,队尾rear = MAXSIZE -1
//这就造成了空队和满队的条件是一样的
//,所以这里牺牲 一个存储位置作为 判定满队的条件
{
printf("队列已满\n");
return true;//返回 1
}
return false ;
}
bool is_empty_sequeue(seq_pqueue q)//判空
{
if(q->front == q->rear)//头尾相连 表示空即初始化状态
{
printf("队列已空\n");
return true;
}
else
{
return false;
}
}
void show_sequeue(seq_pqueue q)//遍历队列
{
if(is_empty_sequeue(q))
{
return;
}
int i;
for(i = (q->front+1)%MAXSIZE;i != (q->rear+1)%MAXSIZE;i = (i+1)%MAXSIZE)//当头没有到尾 说明还有数
//(入队的数可能又从头开始放了)i 自然也得重头来
printf("%3d",q->data[i]);
putchar(10);
}
/*链式存储/
#ifndef _LINKUEUE_H_
#define _LINKUEUE_H_
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>//bool类型头文件
#include<string.h>
typedef int datatype ;
//链式队列节点
typedef struct linkqueuenode{
datatype data;
struct linkqueuenode *next;
}linkqueue_node,*linkqueue_pnode;
//指向队列的头和尾
typedef struct linkueue{
linkqueue_pnode front;//指向队首的前一个位置
linkqueue_pnode rear;//指向队尾巴
}link_queue,*link_pqueue;
link_pqueue init_linkueue(void);//队列创建 及初始化
bool insert_linkueue(link_pqueue q,datatype data);//入队
bool quit_linkueue(link_pqueue q,datatype *D);//出队
bool is_empty_linkueue(link_pqueue q);//判空
void show_linkueue(link_pqueue q);//遍历队列
#endif
```c
#include "linkueue.h"
link_pqueue init_linkueue(void)//队列创建 及初始化
{
link_pqueue q = (link_pqueue)malloc(sizeof(link_queue));//指针域
q->front = (linkqueue_pnode)malloc(sizeof(linkqueue_node));//队列空间申请
//初始化节点为空节点
//为front所指向的 队首的前一个节点位置
if(q == NULL)
{
perror("malloc");
exit(-1);
}
if(q->front == NULL)
{
perror("malloc");
exit(-1);
}
q->front->next = NULL;//空节点
q->rear = q->front;
return q;
}
bool insert_linkueue(link_pqueue q,datatype data)//入队
{
linkqueue_pnode new = (linkqueue_pnode)malloc(sizeof(linkqueue_node));//队列空间申请
if(new == NULL)
{
perror("malloc");
printf("内存申请失败\n");
exit(-1);
}
new->data = data;//放入数据
new->next = NULL;//rear 指向的是当前位置
q->rear->next = new;//前后链表相连
q->rear = q->rear->next;//队尾指向后面
return true;
}
bool quit_linkueue(link_pqueue q,datatype *D)//出队
{
linkqueue_pnode t;
if(is_empty_linkueue(q))
{
return false;
}
t = q->front;//front 指向的是数据的前一个位置
q->front = q->front->next;
*D = q->front->data;
free(t);//这里free掉的是链表头的front,出队的节点作为下一个链表头
return true;
}
bool is_empty_linkueue(link_pqueue q)//判空
{
if(q->front == q->rear)//头尾相连 表示空即初始化状态
{
printf("队列已空\n");
return true;
}
else
{
return false;
}
}
void show_linkueue(link_pqueue q)//遍历队列
{
if(is_empty_linkueue(q))
{
return;
}
linkqueue_pnode p;
for(p = q->front->next;p!=NULL;p = p->next)//队头不为空 继续挪
printf("%3d",p->data);
putchar(10);
}