题目要求:
总结:
(1)由“入队时,允许增加队列占用空间”可知,应使用链式存储结构,因为此条件意味着即使当前队满,队列的存储空间也能增加,而顺序存储结构的最大元素个数是事先就规定好的,故无法达到这一点,使用链式存储结构便于达到,故选择链式结构。
(2)为了重复利用存储空间,采用循环单链表的结构,初始状态如图:
其中front为队头指针,rear为队尾指针,则:
队空时,front==rear;
队满时,rear->next==front;
(3)第一个元素入队之后的队列状态:
(4)略
这道题的解说比较让我费解的是判满,现在我的个人理解是,在第一次出队操作之前,队列就是“满”的。也就意味着第一次出队操作执行之前的入队操作都是要增加新结点的,而且按照视频讲解的意思,rear指针指向最后一个元素所在结点的下一个节点。
编程实现一下这个队列:
#include<stdio.h>
#include<stdlib.h>
//队列结点的基本数据类型定义:
#define ElemType int
typedef struct LinkNode{
ElemType data;
struct LinkNode* next;
}LinkNode;
typedef struct{
LinkNode *front,*rear;
}LinkQueue;
void InitQueue(LinkQueue &Q)
{
Q.front=(LinkNode*)malloc(sizeof(LinkNode));
Q.front->next=
Q.rear=Q.front;
}
//入队操作:
void EnQueue(LinkQueue &Q,ElemType x)
{
LinkNode *p;
if(Q.front==(Q.rear->next))
{
p=(LinkNode*)malloc(sizeof(LinkNode));
Q.rear->next=p;
p->next=Q.front;
}
Q.rear->data=x;
Q.rear=Q.rear->next;
}
//判空操作:
bool QueueEmpty(LinkQueue Q)
{
if(Q.front==Q.rear)return true;
else return false;
}
//出队操作:
bool DeQueue(LinkQueue &Q,ElemType &x)
{
if(Q.front==Q.rear)
{
printf("\n队列为空,出队失败.\n");
return false;
}
x=Q.front->data;
Q.front=Q.front->next;
return true;
}
void DestroyQueue(LinkQueue &Q)
{
LinkNode *p=Q.front->next,*q;
while(p->next!=Q.front)
{
q=p;
p=p->next;
free(q);
}
free(p);
free(Q.front);
Q.front=NULL;
Q.rear=NULL;
}
int main()
{
LinkQueue Q;
InitQueue(Q);
ElemType x;
printf("\n元素开始入队:\n");
scanf("%d",&x);
while(x!=9999)
{
EnQueue(Q,x);
scanf("%d",&x);
}
printf("\n元素开始出队:\n");
while(!QueueEmpty(Q))
{
DeQueue(Q,x);
printf("%d ",x);
}
printf("\n");
DestroyQueue(Q);
printf("\n成功销毁此队列!\n");
return 0;
}