题目:假设以带头结点的循环链表表示队列,并且只设一个指针指向队尾元素站点(注意不设头指针) ,试编写相应的置空队、判队空 、入队和出队等算法。
定义循环队列队列:
typedef struct QNode{
ElemType data; //数据域
struct QNode *next; //指针域
}QNode,*QueuePtr;
typedef struct{ //不设头指针
QueuePtr rear;//尾指针
}LinkQueue;
1.置空循环队列
思路:置空队就是将除了头结点以外的其他结点全部删除。
算法描述:
Status InitEmpty(LinkQueue &Q){
Q.rear=Q.rear->next; //将尾指针指向头指针
while(Q.rear=Q.rear->next){
struct QNode *s; //结点s暂存要删除的结点
s=(ElemType *)malloc(sizeof(Elemtype));
s=Q.rear->next->next; //s指向头结点
Q.rear->next->next=s->next;
free(s); //删除s结点
}
return OK;
}
2.判断队列是否为空
思路:因为尾指针指向最后一个结点,所以当尾指针指向其本身即Q.rear->next==Q.rear时,队列为空。
算法描述:
Status IsEmpty(LinkQueue &Q){
if(Q.rear->next==Q.rear){
return OK; //队列为空
}else{
return ERROR; //队列不为空
}
}
3.循环队列入队
算法描述:
Status InQueue(LinkQueue &Q,ElemType e){ //将数据e插入队列(尾部)
struct QNode *p;
p=(ElemType *)malloc(sizeof(ElemType)); //开辟一个空间,结点记为p
if(!p){
return ERROR; //存储空间分配失败
}
p->data=e; //p的数据域存放e
p-next=Q.rear->next; //p指向头结点
Q.rear-next=p; //尾结点指向p
Q.rear=p; //p为尾结点
return OK;
}
4.循环队列出队
算法描述:
Status OutQueue(LinkQueue &Q,ElemType &e){ //删除头结点并把头结点数据域中的值赋给e
if(Q.rear->next==Q.rear){
return ERROR; //队空
}
struct QNode *p;
p=Q.rear->next->next; //p指向头结点
e=p->data; //e取头结点数据域的值
if(p==Q.rear){ //头结点和尾结点相等,即队列中只有一个元素
Q.rear=Q.rear->next;
Q.rear->next=p->next;
}else{ //队列中有多个元素
Q.rear->next->next=p->next;
free(p);
}
return OK;
}
5.循环队列初始化
思路:生成一个头结点,并分配存储空间,尾指针指向头结点。
算法描述:
Status InitQueue(LinkQueue &Q){
Q.rear=(ElemType *)malloc(sizeof(ElemType));
if(!Q.rear){
return ERROR;
}
Q.rear->next=Q.rear;
return OK;
}