链队
队列链式存储结构其实就是链表,只不过这个链表的删除和插入操作只能在一端进行。
队列的链式存储结构
链队的结点类型
typedef struct _qnode{
ElemType data;
struct _qnode *next;
}qnode;
和单链表一样,链队的结点由数据域和指针域构成。
定义一个结构存储队头和队尾指针。
typedef struct _lQueue{
qnode *front;
qnode *rear;
}lQueue;
单链表版链队
初始化队
void
initQueue( lQueue **q )
{
*q = ( lQueue* )malloc( sizeof( lQueue ) );
(*q)->front = (*q)->rear = NULL;
}
销毁队
void
destroyQueue( lQueue *q )
{
while( q->front ){
q->rear = q->front->next;
free( q->front );
q->front = q->rear;
}
free( q );
}
判断队列是否为空
void
queueEmpty( lQueue *q )
{
return ( q->rear == NULL );
}
进队
第一个元素进入一个空队后,front
和rear
都指向这个元素,后继的元素陆续进队,rear
指针始终指向最后一个进队的元素。
void
enQueue( lQueue *q, ElemType e )
{
qnode *p = ( qnode* )malloc( sizeof( qnode ) );
p->data = e;
p->next = NULL;
if( q->rear == NULL ){
q->front = q->rear = p;
}else{
q->rear->next = p;
q->rear = p;
}
}
出队
int
deQueue( lQueue *q, ElemType *e )
{
qnode *t;
if( q->rear == NULL ){ //队空时不能出队
return FALSE;
}
t = q->front;
if( q->front == q->rear ){ //队列只有一个数据结点
q->front = q->rear = NULL;
}else{
q->front = q->front->next;
}
*e = q->front->data;
free(t);
return TRUE;
}
循环链表版链队
用循环链表构建链队时,可以只用一个rear
指针来代替lQueue
结构。
初始化队
我们采用不带头结点的循环单链表作为队列,所以在初始化队列时将rear
置空即可
void
initQueue( qnode **rear )
{
*rear = NULL;
}
销毁队
void
destroyQueue( qnode *rear )
{
qnode *p, *t;
if( rear != NULL ){
p = rear->next;
while( p != rear ){
t = p->next;
free( p );
p = t;
}
free( rear );
}
}
判断队是否为空
int
queueEmpty( qnode *rear )
{
return ( rear == NULL );
}
进队
第一个元素进队,让第一个元素自己指向自己,rear
指向这个元素,后继元素进队时都将next
指向队头元素,rear
始终指向队尾元素,这样一来只需要rear->next
一步操作即可找到队头
void
enQueue( qnode **rear, ElemType e )
{
qnode *n = ( qnode* )malloc( sizeof( qnode ) );
n->data = e;
if( *rear == NULL ){ //当队为空时
n->next = n;
*rear = n;
}else{
n->next = (*rear)->next;
(*rear)->next = n;
*rear = n;
}
}
出队
元素出队时,用rear->next->next
找到队头元素的后继结点,将其与队尾相连
int
deQueue( qnode **rear, ElemType *e )
{
qnode *t;
if( *rear == NULL ){
return FALSE;
}
if( (*rear)->next == *rear ){ //原来的队列中只有一个结点
*e = (*rear)->data;
free( *rear );
*rear = NULL;
}else{
t = (*rear)->next;
*e = t->data;
(*rear)->next = t->next;
free( t );
}
return TRUE;
}