队列-顺序结构

队列假溢出,循环顺序牺牲一个空间 (Q.rear+1)%MAXSIZE == Q.front 判断是否满了
/**
队列的特点就是先进先出。在一个连续的空间中,为了避免队列假溢出(出比进快),我们始终保留一个空空间用来作为标记,防止假溢出
*/
//定义状态
typedef int STATUS;
//定义数据类型
typedef int ELEMENT;
/*循环队列的顺序结构*/
typedef struct Queue {
//分配一个连续的空间,将用于队列元素的储存
ELEMENT data[MAXSIZE];
int front;//队列头
int rear;//对列尾
}Queue;
//初始化
STATUS Queue_init(Queue *Q) {
//首尾相等
Q->front = Q->rear = 0;
return OK;
}
//队列清空
STATUS Queue_clear(Queue *Q) {
//同样也是清空,至于已经有的元素不需要释放,因为数组空间已开始就已经分配20个
Q->front = Q->rear = 0;
return OK;
}
//队列是否为空
STATUS Queue_isEmpty(Queue Q) {
if (Q.front == Q.rear) {//只要满足front == rear,就是空了,不需要满足front == rear == 0,因为front 可以不为0
return TRUE;
} else {
return FALSE;
}
}
//队列是否满
STATUS Queue_isFull(Queue Q) {
if ((Q.rear+1)%MAXSIZE == Q.front) {
return TRUE;
} else {
return FALSE;
}
}
//元素的个数,也就是当前队列的长度
STATUS Queue_lenght(Queue Q) {
//因为是队列,在一个连续的空间 rear的数值可能比front的数值小会得到负数,所以要取模
return (Q.rear - Q.front + MAXSIZE ) % MAXSIZE;
}
//获取对头元素
STATUS Queue_top(Queue Q,ELEMENT *e) {
if (Queue_isEmpty(Q)) {
return ERROR;
}
//把对头元素赋值给e
*e = Q.data[Q.front];
return OK;
}
//队列进入
STATUS Queue_en(Queue *Q,ELEMENT e) {
//队列已满
if (Queue_isFull(*Q)) {
return ERROR;
}
//将元素e赋值给队尾
Q->data[Q->rear] = e;
//rear指针向后移动一位,若到最后则转到数组头部;
Q->rear = (Q->rear + 1)%MAXSIZE;
return OK;
}
//队列出队
STATUS Queue_de(Queue *Q,ELEMENT *e) {
//队列已满
if (Queue_isFull(*Q)) {
return ERROR;
}
//保存出队元素赋值给e
*e = Q->data[Q->front];
//front 指针向后移动一位,若到最后则转到数组头部
Q->front = (Q->front + 1)%MAXSIZE;
return OK;
}
//队列遍历
STATUS Queue_traverse(Queue Q) {
int i = Q.front;
while ((i+Q.front) != Q.rear) {
printf("%d ",Q.data[i]);
i = (i+1)%MAXSIZE;
}
printf("\n");
return OK;
}
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
STATUS j;
int i=0;
ELEMENT d;
Queue Q;
Queue_init(&Q);
printf("初始化队列后,队列空否?%u(1:空 0:否)\n",Queue_isEmpty(Q));
printf("入队:\n");
while (i < 10) {
Queue_en(&Q, i);
i++;
}
Queue_traverse(Q);
printf("队列长度为: %d\n",Queue_lenght(Q));
printf("现在队列空否?%u(1:空 0:否)\n",Queue_isEmpty(Q));
printf("出队:\n");
//出队
Queue_de(&Q, &d);
printf("出队的元素:%d\n",d);
Queue_traverse(Q);
//获取队头
j = Queue_top(Q,&d);
if(j)
printf("现在队头元素为: %d\n",d);
Queue_clear(&Q);
printf("清空队列后, 队列空否?%u(1:空 0:否)\n",Queue_isEmpty(Q));
return 0;
}
栈-链表结构
typedef int STATUS;
typedef int ELEMENT;
/*节点结构*/
typedef struct Node {
ELEMENT data;
struct Node *next;
}Node, *LinkNodePtr;
/*队列的链表结构*/
typedef struct QueueNode {
/* 队头、队尾指针 */
LinkNodePtr front;
LinkNodePtr rear;
}QueueLink;
//初始化
STATUS Queue_init(QueueLink *Q) {
//1. 头/尾指针都指向新生成的结点
Q->front = Q->rear = (LinkNodePtr)malloc(sizeof(Node));
//2.判断是否创建新结点成功与否
if (Q->front == NULL || Q->rear == NULL) {
return ERROR;
}
//3.头结点的指针域置空,当然也可以是Q->rear->data = NULL;因为两个指针指向同一个区域
Q->front->next = NULL;
return OK;
}
//队列销毁
STATUS Queue_destory(QueueLink *Q) {
//遍历整个队列,销毁队列每个节点
while (Q->front) {
Q->rear = Q->front->next;
free(Q->front);
Q->front = Q->rear;
}
return OK;
}
//队列置空
STATUS Queue_clear(QueueLink *Q) {
//1.临时变量
LinkNodePtr p,q;
//2.先将rear 指向 front
Q->rear = Q->front;
//3.用p 拿到front->next
p = Q->front->next;
//4.将Q->front->next置空
Q->front->next = NULL;
//将p中的数据释放
while (p) {
q = p;
p = p->next;
free(q);
}
return OK;
}
//为空判断
STATUS Queue_isEmpty(QueueLink Q) {
if (Q.rear == Q.front) {
return TRUE;
} else {
return FALSE;
}
}
//长度
STATUS Queue_lenght(QueueLink Q) {
int i = 0;
LinkNodePtr temp = Q.front;
while (temp != Q.rear) {
temp = temp->next;
i ++;
}
return i;
}
//入队
STATUS Queue_en(QueueLink *Q,ELEMENT e) {
//新增入队节点
LinkNodePtr p = malloc(sizeof(Node));
if (p == NULL) {
return ERROR;
}
//节点赋值
p->data = e;
p->next = NULL;
//插入队尾
Q->rear->next = p;
//修改队尾指针
Q->rear = p;
return OK;
}
//出列
STATUS Queue_de(QueueLink *Q,ELEMENT *e) {
//是否为空
if (Queue_isEmpty(*Q)) {
return ERROR;
}
//返回出对列元素
*e = Q->front->data;
//新建临时结点
LinkNodePtr temp;
//将要删除的队头结点暂时存储在temp
temp = Q->front;
//将原队列头结点的后继p->next 赋值给头结点后继
Q->front = Q->front->next;
//若队头就是队尾,则删除后将rear指向头结点.
if (Q->front == Q->rear) {
Q->rear = Q->front;
}
//释放节点
free(temp);
return OK;
}
//头元素
STATUS Queue_top(QueueLink Q,ELEMENT *e) {
if (Queue_isEmpty(Q)) {
return ERROR;
}
*e = Q.front->next->data;
return OK;
}
//遍历
STATUS Queue_traverse(QueueLink Q) {
if (Queue_isEmpty(Q)) {
return ERROR;
}
LinkNodePtr temp;
temp = Q.front->next;
while (temp) {
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
return OK;
}
int main(int argc, const char * argv[]) {
// insert code here...
printf("链队列的表示与操作!\n");
STATUS iStatus;
ELEMENT d;
QueueLink q;
//1.初始化队列q
iStatus = Queue_init(&q);
//2. 判断是否创建成
if (iStatus) {
printf("成功地构造了一个空队列\n");
}
//3.判断队列是否为空
printf("是否为空队列?%d (1:是 0:否)\n",Queue_isEmpty(q));
//4.获取队列的长度
printf("队列的长度为%d\n",Queue_lenght(q));
//5.插入元素到队列中
Queue_en(&q, -3);
Queue_en(&q, 6);
Queue_en(&q, 12);
printf("队列的长度为%d\n",Queue_lenght(q));
printf("是否为空队列?%d (1:是 0:否)\n",Queue_isEmpty(q));
//6.遍历队列
printf("队列中的元素如下:\n");
Queue_traverse(q);
//7.获取队列头元素
iStatus = Queue_top(q, &d);
if (iStatus == OK) {
printf("队头元素是:%d\n",d);
}
//8.删除队头元素
iStatus = Queue_de(&q, &d);
if (iStatus == OK) {
printf("删除了的队头元素为:%d\n",d);
}
//9.获取队头元素
iStatus = Queue_top(q, &d);
if (iStatus == OK) {
printf("新的队头元素为:%d\n",d);
}
//10.清空队列
Queue_clear(&q);
//11.销毁队列
Queue_destory(&q);
return 0;
}