算法设计:
假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点(注意不设头指针) ,试编写相应的置空队、判队空 、入队和出队算法。
链队结构:
typedef struct queuenode{
Datatype data;
struct queuenode *next;
}QueueNode; //结点类型的定义
typedef struct{
queuenode *rear;
}LinkQueue; //只设一个指向队尾元素的指针
(1)置空:
void InitQueue( LinkQueue *Q)
{ //置空队,使头结点成为队尾元素
QueueNode *s;
Q->rear = Q->rear->next;//将队尾指针指向头结点
while (Q->rear!=Q->rear->next)//当队列非空,将队中元素逐个出队
{
s=Q->rear->next;
Q->rear->next=s->next;
delete s;
}//回收结点空间
}
(2)判空:
int EmptyQueue( LinkQueue *Q)
{ //判队空。当头结点的next指针指向自己时为空队
return Q->rear->next->next==Q->rear->next;
}
(3)入队:
void EnQueue( LinkQueue *Q, Datatype e)
{ //入队,在尾结点处插入元素
QueueNode *p=new QueueNode;//申请新结点
p->data=e;
p->next=Q->rear->next;//初始化新结点并链入
Q-rear->next=p;
Q->rear=p;//将尾指针移至新结点
}
(4)出队:
Datatype DeQueue( LinkQueue *Q)
{//出队,把头结点后的元素删除
Datatype t;
QueueNode *p;
if(EmptyQueue( Q ))
Error("队列为空");
p=Q->rear->next->next; //p指向将要删除的结点
e=p->data; //保存结点中数据
if (p==Q->rear)
{//当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点
Q->rear = Q->rear->next;
Q->rear->next=p->next;
}
else
Q->rear->next->next=p->next;//摘下结点p
delete p;//释放被删结点
return e;
}