假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾结点,但不设头指针。试设计相应的入队和出队算法。
#include <stdio.h>
#include <stdlib.h>#define ERROR -1
#define OK 0typedef int QElemType; // 假设队列中元素类型为 inttypedef struct LNode
{QElemType data;struct LNode *next;
} LNode, *LinkQueue; // 带头结点的循环链表,不设头指针// 初始化队列,包括创建头结点,并让尾指针指向头结点
LinkQueue InitQueue()
{LinkQueue rear = (LinkQueue)malloc(sizeof(LNode));if (!rear){exit(ERROR); // 内存分配失败,退出程序}rear->next = rear; // 头结点的 next 指针指向自己,表示队列为空return rear;
}// 入队操作,尾插法
int EnQueue(LinkQueue rear, QElemType e)
{LNode *p = (LNode *)malloc(sizeof(LNode));if (!p){return ERROR; // 内存分配失败}p->data = e;p->next = rear->next; // 新节点的 next 指向头结点rear->next = p; // 尾指针指向新节点rear = p; // 更新尾指针为新节点return OK;
}// 出队操作
int DeQueue(LinkQueue rear, QElemType &e)
{if (rear->next == rear){return ERROR; // 队列为空,无法出队}LNode *p = rear->next->next; // 头结点的下一个节点e = p->data; // 获取头结点的下一个节点的元素值if (p == rear) // 如果头结点的下一个节点是尾节点{rear->next = rear; // 则删除后队列为空}else{rear->next->next = p->next; // 头结点的下一个节点指向原来尾节点的下一个节点}free(p); // 释放原来头结点的下一个节点return OK;
}int main()
{LinkQueue rear = InitQueue();QElemType e;// 入队操作示例EnQueue(rear, 1);EnQueue(rear, 2);EnQueue(rear, 3);// 出队操作示例DeQueue(rear, e);printf("%d\n", e); // 输出 1DeQueue(rear, e);printf("%d\n", e); // 输出 2DeQueue(rear, e);printf("%d\n", e); // 输出 3free(rear); // 释放头结点return 0;
}
假设以数组Q[m]存放循环队列中的元素,同时设置一个标志tag,以tag==0和tag==1来区别在对头指针(front)和队尾指针(rear)相等时,队列状态为空还是满。试编写与此结构相应的入队(enQueue)和出对(deQueue)算法。
#include <stdio.h>
#include <stdlib.h>#define MAXSIZE 100 // 假设队列的最大长度为 100typedef int QElemType; // 假设队列中元素类型为 inttypedef struct
{QElemType data[MAXSIZE]; // 用数组存放队列元素int front; // 头指针int rear; // 尾指针int tag; // 标志,0 表示队列空,1 表示队列满
} SqQueue;// 初始化队列
void InitQueue(SqQueue &Q)
{Q.front = 0; // 初始时头指针指向队列头部Q.rear = 0; // 初始时尾指针指向队列头部Q.tag = 0; // 初始时队列为空
}// 入队操作
int enQueue(SqQueue &Q, QElemType e)
{if (Q.front == Q.rear && Q.tag == 1){printf("队列已满,无法入队\n");return -1; // 队列满,入队失败}Q.data[Q.rear] = e; // 将新元素放入尾指针所指向的位置Q.rear = (Q.rear + 1) % MAXSIZE; // 尾指针后移一位,循环队列的实现Q.tag = 1; // 标志队列为非空return 0; // 入队成功
}// 出队操作
int deQueue(SqQueue &Q, QElemType &e)
{if (Q.front == Q.rear && Q.tag == 0){printf("队列为空,无法出队\n");return -1; // 队列空,出队失败}e = Q.data[Q.front]; // 获取头指针所指向的元素Q.front = (Q.front + 1) % MAXSIZE; // 头指针后移一位,循环队列的实现Q.tag = 0; // 标志队列为空return 0; // 出队成功
}int main()
{SqQueue Q;InitQueue(Q);// 入队操作示例enQueue(Q, 1);enQueue(Q, 2);enQueue(Q, 3);// 出队操作示例QElemType e;deQueue(Q, e);printf("%d\n", e); // 输出 1deQueue(Q, e);printf("%d\n", e); // 输出 2deQueue(Q, e);printf("%d\n", e); // 输出 3return 0;
}