队列的基本操作!
1.链式队列
//队列结点结构体
typedef struct QNode
{ QElemType data;
QNode *next;
}*Queueptr;
-——————————————-
//指向结点的指针
struct LinkQueue
{ Queueptr front,rear;
}
[cpp] view plain copy print ?
- void InitQueue(LinkQueue &Q)
- { // 构造一个空队列Q
- if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))
- exit(OVERFLOW);
- Q.front->next=NULL;
- }
- void DestroyQueue(LinkQueue &Q)
- { // 销毁队列Q(无论空否均可)
- while(Q.front)
- {
- Q.rear=Q.front->next;
- free(Q.front);
- Q.front=Q.rear;//释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空
- }
- }
- void ClearQueue(LinkQueue &Q)
- { // 将Q清为空队列
- QueuePtr p,q;
- Q.rear=Q.front;
- p=Q.front->next;
- Q.front->next=NULL;//只留下头结点
- while(p)
- {
- q=p;
- p=p->next;
- free(q);
- }
- }
- Status QueueEmpty(LinkQueue Q)
- { // 若Q为空队列,则返回TRUE,否则返回FALSE
- if(Q.front->next==NULL)//注意不要把链式队列的判空条件与循环队列混淆
- return TRUE;
- else
- return FALSE;
- }
- int QueueLength(LinkQueue Q)
- { // 求队列的长度
- int i=0;
- QueuePtr p;
- p=Q.front;
- while(Q.rear!=p)
- {
- i++;
- p=p->next;
- }
- return i;
- }
- Status GetHead(LinkQueue Q,QElemType &e)
- { // 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR
- QueuePtr p;
- if(Q.front==Q.rear)
- return ERROR;
- p=Q.front->next;
- e=p->data;
- return OK;
- }
- void EnQueue(LinkQueue &Q,QElemType e)
- { // 插入元素e为Q的新的队尾元素
- QueuePtr p;
- if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败
- exit(OVERFLOW);
- p->data=e;
- p->next=NULL;
- Q.rear->next=p;
- Q.rear=p;
- }
- Status DeQueue(LinkQueue &Q,QElemType &e)
- { // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR
- QueuePtr p;
- if(Q.front==Q.rear)
- return ERROR;
- p=Q.front->next;
- e=p->data;
- Q.front->next=p->next;
- if(Q.rear==p)
- Q.rear=Q.front;//如果只有一个节点,那么删除这个节点后rear指针也就丢了,需重新赋值
- free(p);
- return OK;
- }
- void QueueTraverse(LinkQueue Q,void(*vi)(QElemType))
- { // 从队头到队尾依次对队列Q中每个元素调用函数vi()
- QueuePtr p;
- p=Q.front->next;
- while(p)
- {
- vi(p->data);
- p=p->next;
- }
- printf(“\n”);
}</STRONG>
void InitQueue(LinkQueue &Q) { // 构造一个空队列Q if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)))) exit(OVERFLOW); Q.front->next=NULL; } void DestroyQueue(LinkQueue &Q) { // 销毁队列Q(无论空否均可) while(Q.front) { Q.rear=Q.front->next; free(Q.front); Q.front=Q.rear;//释放一块内存要做两点:1.释放指向它的指针。2.将该指针指向空 } } void ClearQueue(LinkQueue &Q) { // 将Q清为空队列 QueuePtr p,q; Q.rear=Q.front; p=Q.front->next; Q.front->next=NULL;//只留下头结点 while(p) { q=p; p=p->next; free(q); } } Status QueueEmpty(LinkQueue Q) { // 若Q为空队列,则返回TRUE,否则返回FALSE if(Q.front->next==NULL)//注意不要把链式队列的判空条件与循环队列混淆 return TRUE; else return FALSE; } int QueueLength(LinkQueue Q) { // 求队列的长度 int i=0; QueuePtr p; p=Q.front; while(Q.rear!=p) { i++; p=p->next; } return i; } Status GetHead(LinkQueue Q,QElemType &e) { // 若队列不空,则用e返回Q的队头元素,并返回OK,否则返回ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; return OK; } void EnQueue(LinkQueue &Q,QElemType e) { // 插入元素e为Q的新的队尾元素 QueuePtr p; if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败 exit(OVERFLOW); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; } Status DeQueue(LinkQueue &Q,QElemType &e) { // 若队列不空,删除Q的队头元素,用e返回其值,并返回OK,否则返回ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front;//如果只有一个节点,那么删除这个节点后rear指针也就丢了,需重新赋值 free(p); return OK; } void QueueTraverse(LinkQueue Q,void(*vi)(QElemType)) { // 从队头到队尾依次对队列Q中每个元素调用函数vi() QueuePtr p; p=Q.front->next; while(p) { vi(p->data); p=p->next; } printf(“\n”); }
2.顺序队列—-循环队列
性质如下:
1.头指针指向对头元素,尾指针指向队尾的下一个位置。(这里的指针都是为指针,实际是数组序号)
2.为了区分队满与对空,则定义一个存储空间为MAX_QSIZE大小的队列只允许存放MAX_QSIZE-1个数据。
3.判空条件为:if(Q.front ==Q.rear) return true;
判满条件为:if((Q.rear+1)%MAX_QSIZE==Q.front) return true;
4.循环队列的长度为:(Q.read-Q.front+MAX_SIZE)%MAX_QSIZE
5.当删除对头元素或者在对尾插入元素时指针均需向后移动。操作为:
Q.rear=(Q.rear+1)%MAX_QSIZE;
Q.front=(Q.front+1)%MAX_QSIZE;
结构体定义如下:
struct SqQueue
{QElemType *base;//指向开辟的空间的首地址
int front;
int rear;
}
[cpp] view plain copy print ?
- void InitQueue(SqQueue &Q)
- { // 构造一个空队列Q
- Q.base=(QElemType *)malloc(MAX_QSIZE*sizeof(QElemType));
- if(!Q.base) // 存储分配失败
- exit(OVERFLOW);
- Q.front=Q.rear=0;
- }
- void DestroyQueue(SqQueue &Q)
- { // 销毁队列Q,Q不再存在
- if(Q.base)
- free(Q.base);
- Q.base=NULL;
- Q.front=Q.rear=0;
- }
- void ClearQueue(SqQueue &Q)
- { // 将Q清为空队列
- Q.front=Q.rear=0;
- }
- Status QueueEmpty(SqQueue Q)
- { // 若队列Q为空队列,则返回TRUE;否则返回FALSE
- if(Q.front==Q.rear) // 队列空的标志
- return TRUE;
- else
- return FALSE;
- }
- int QueueLength(SqQueue Q)
- { // 返回Q的元素个数,即队列的长度
- return(Q.rear-Q.front+MAX_QSIZE)%MAX_QSIZE;
- }
- Status GetHead(SqQueue Q,QElemType &e)
- { // 若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
- if(Q.front==Q.rear) // 队列空
- return ERROR;
- e=Q.base[Q.front];//等价于e=*(Q.base+Q.front)
- return OK;
- }
- Status EnQueue(SqQueue &Q,QElemType e)
- { // 插入元素e为Q的新的队尾元素
- if((Q.rear+1)%MAX_QSIZE==Q.front) // 队列满
- return ERROR;
- Q.base[Q.rear]=e;//等价于*(Q.base+Q.rear)=e
- Q.rear=(Q.rear+1)%MAX_QSIZE;
- return OK;
- }
- Status DeQueue(SqQueue &Q,QElemType &e)
- { // 若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
- if(Q.front==Q.rear) // 队列空
- return ERROR;
- e=Q.base[Q.front];
- Q.front=(Q.front+1)%MAX_QSIZE;
- return OK;
- }
- void QueueTraverse(SqQueue Q,void(*vi)(QElemType))
- { // 从队头到队尾依次对队列Q中每个元素调用函数vi()
- int i;
- i=Q.front;
- while(i!=Q.rear)
- {
- vi(Q.base[i]);
- i=(i+1)%MAX_QSIZE;
- }
- printf(“\n”);
- }
还没有评论,来说两句吧...