队列的链式存储---链表实现
/* 队列的链式存储 */ /* with no header */ struct Node; struct LinkQueue; typedef struct Node *PtrToNode; typedef struct LinkQueue *PtrTorf; struct Node{ ElementType X; PtrToNode Next; }; struct LinkQueue{ PtrToNode rear; PtrToNode front; }; int IsEmpty(PtrTorf PtrQ ) { return PtrQ->front == NULL; } ElemenType DeleQ(PtrTorf PtrQ ) { PtrToNode TmpCell; ElementType X; if( IsEmpty( PtrQ ) ) { Error("队列是空"); retutn; } TmpCell = PtrQ->front; X = TmpCell->Element; if( PtrQ->front == PtrQ->rear ) { PtrQ->front = NULL; PtrQ->rear = NULL; } else PtrQ->front = TmpCell->Next; free( TmpCell ); return X; } void AddQ( PtrTorf PtrQ ) { PtrToNode TmpCell; TmpCell = malloc(sizeof(struct Node )); if(TmoCell == NULL ) Error("out if space "); TmpCell->Next == NULL; TmpCell->Element = X; if( !(IsEmpy( PtrQ ))){//队列非空时,也只有rear再动 PtrQ->rear->Next = TmpCell; PtrQ->rear = TmpCell; } else PtrQ->rear = Ptr->front = TmpCell;//队列的链式存储,front和rear都指向一处时,才表示有一个元素,如果都指向NULL就表示空 }
///////////////////////////2015/11/23 更正如下:
更正:在DeleteQ()中,当删除到最后一个元素,Q->front->Next会被置为NULL,而Q->rear所指处为无物,尽管继续AddQ()不会报错,可是此时已与Q->front连接不上
解决方法:在DeleteQ()中判空,如果为空,将rear重设为指向header
int DeleteQ(struct LinQ * Q){ int res; PtrToNode firstCell; firstCell = Q->front->Next; res = firstCell->one_num; Q->front->Next = firstCell->Next; free(firstCell); if(IsEmpty( Q )){ Q->rear = Q->front; } return res; } int IsEmpty(struct LinQ *Q){ return (Q->front->Next ==NULL); }
///////////////////////////////////////////////////////////////////////////////////
该队列的链表实现没有使用头结点
如果rear和front指针都为空表示队列为空
如果rear和front相等(指向同一个地方)队列有1个元素(结点)
使用这种不带头结点的实现,需要在DeleteQ最后一个元素时,把队尾指针弄成NULL
在AddQ第一个元素时,需要修改队首指针为第一个结点的地址