链队

队列链式存储结构其实就是链表,只不过这个链表的删除和插入操作只能在一端进行。

队列的链式存储结构

链队的结点类型

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 );
}

进队

第一个元素进入一个空队后,frontrear都指向这个元素,后继的元素陆续进队,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;
}
posted @ 2020-07-23 11:44  LanceHansen  阅读(108)  评论(0编辑  收藏  举报