1、若希望循环队列中的元素都能得到利用,则需要设置一个标志域tag,并以tag的值为0或1来区分队头指针front和队尾指针rear相同时的队列是“空”还是“满”。试编写于此结构相应的入队和出队算法。
新增一个标志域
#define MaxSize 50
typedef struct
{
ElemType data[MaxSize];
int front,rear,tag;
}SqQueue;
当 front等于rear的时候无法判断是满还是空,新增一个条件tag。
入队:
void Enqueue(SqQueue &Q,Elemtype x)
{
if(Q.front == Q.rear && Q.tag == 1)
return;
Q.data[Q.rear] = x;
Q.rear= (Q.rear+1)%MaxSize;
Q.tag = 1;
}
出队:
void Dequeue(SqQueue &Q)
{
if(Q.front == Q.rear && Q.tag == 0)
return;
Q.data[Q.front] = x;
Q.front= (Q.front+1)%MaxSize;
Q.tag = 0;
}
2、利用两个栈S1,S2来模拟一个队列,且已知栈的4个运算定义如下:
Push(S,x); //元素x入栈
Pop(S,x); //S出栈并将出栈的值赋给x
StackEmpty(S); //判断栈是否为空
StackOverflow(S); //判断栈是否满
如何利用栈的运算来实现该队列的3个运算(形参自己设计)
Enqueue; //将元素x入队
Dequeue; //出队,并将出队元素存储在x中
QueueEmpty; //判断队列是否为空
设计思路:
假设入队序列为abc d e fgh(中间断开表示不是同一批入队)
入队的话就只需要入栈S1,当S2为空的时候,使S1暂停入队,将S1中的元素出栈并入栈到S2中,出队的时候出栈S2即可。
实现我就不写了,太浪费时间了。
3、请设计一个队列,要求满足:
①初始时队列为空;
②入队时,允许增加队列占用空问;
③出队后,出队元素所占用的空间可重复使用,即整个队列所占用的空间只增不减;
④入队操作和出队操作的时间复杂度始终保持为 0(1) 。
请回答下列问题:
1)该队列是应选择链式存储结构,还是应选择顺序存储结构?
应该选择链式存储结构,因为入队的时候增加存储空间比较方便。
2)画出队列的初始状态,并给出判断队空和队满的条件。
队空的时候*head == *tail
队满的时候tail->next ==NULL;
3)画出一个元素入队后的队列状态。
4)给出入队操作和出队操作的基本过程。
我用画图来说明基本逻辑,然后给出关键步骤代码
入队:
//SqNode *p = (SqNode *p )alloc(sizeof(SqNode));
//p->next = NULL;
//tail->next = p;
//tail = tail->next;
//p = NULL;
//入队元素假设为Elem
if(tail->next != NULL)
{
tail->next->data = Elem;
tail = tail->next;
}
else
{
SqNode *p = (SqNode *p )alloc(sizeof(SqNode));
p->data = Elem;
p->next = tail->next;
tail->next = p;
tail = tail->next;
p = NULL;
}
出队:
//tail->next = head->next;
//head->next = head->next->next;
//head->next->next = NULL;
SqNode *p = head->next;
head->next = p->next;
p->next = tail->next;
tail->next = p;
p =NULL;
人,总是要有一点精神的,不是吗