一、概述:
像栈一样,队列(queue)也是表。然而,使用队列时插入在一端进行而删除在另一端进行。
队列的基本操作是Enqueue(入队),它是在表的末端(叫做队尾(rear)插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(叫做队头(front)的元素。如图1所示显示一个队列的抽象模型。
图1 队列模型
二、实现
如同栈的情形一样,对于队列而言任何表的实现都是合法的。像栈一样,对于每一种操作,链表实现和数组实现都给出快速的
O(1)运行时间。
1. 队列的链表实现
文件名:queue_list.h
#ifndef _QUEUE_LIST_H文件名:queue_list.c
#define _QUEUE_LIST_H
#define ElementType int
struct Node;
struct QNode;
typedef struct Node *PtrToNode;
typedef PtrToNode Queue;
int IsEmpty( Queue Q );
Queue CreateQueue( void );
void DisposeQueue( Queue Q );
void MakeEmpty( Queue Q );
void Enqueue( ElementType X, Queue Q );
ElementType Front( Queue Q );
void Dequeue( Queue Q );
ElementType FrontAndDequeue( Queue Q );
#endif /* _QUEUE_LIST_H */
#include "queue_list.h"文件名:queue_list_main.c
#include "fatal.h"
typedef struct QNode
{
ElementType Element;
struct QNode *Next;
}QNode, *QNodePtr;
struct Node {
QNodePtr Front;
QNodePtr Rear;
};
int
IsEmpty( Queue Q )
{
return Q->Front == Q->Rear;
}
Queue
CreateQueue( void )
{
Queue Q;
Q = malloc( sizeof( struct Node ) );
Q->Front = Q->Rear = malloc( sizeof( struct QNode ) );
if (!Q->Front)
FatalError( "Out of space!!!");
Q->Front->Next = NULL;
return Q;
}
void
MakeEmpty( Queue Q )
{
if( Q == NULL )
Error( "Must use CreateQueue first" );
else
while( !IsEmpty( Q ) )
Dequeue( Q );
}
void
DisposeQueue( Queue Q )
{
while( Q->Front ) {
Q->Rear = Q->Front->Next;
free( Q->Front );
Q->Front = Q->Rear;
}
printf( "\nDispose queue completed!!!" );
}
void
Enqueue( ElementType X, Queue Q )
{
QNodePtr p;
p = malloc( sizeof( QNode ) );
if (!p)
FatalError( "Out of space!!!" );
p->Element = X;
p->Next = NULL;
Q->Rear->Next = p;
Q->Rear = p;
}
ElementType
Front( Queue Q )
{
if ( !IsEmpty( Q ) )
return Q->Front->Next->Element;
return 0; /* Return value used to avoid warning */
}
void
Dequeue( Queue Q )
{
if ( !IsEmpty( Q ) )
{
QNodePtr p;
p = malloc( sizeof( QNode ) );
if (!p)
FatalError( "Out of space!!!" );
p = Q->Front->Next;
Q->Front->Next = p->Next;
if ( Q->Rear == p )
Q->Rear = Q->Front;
free( p );
}
}
ElementType
FrontAndDequeue( Queue Q )
{
if ( !IsEmpty( Q ) )
{
QNodePtr p;
p = malloc( sizeof( QNode ) );
if (!p)
FatalError( "Out of space!!!" );
p = Q->Front->Next;
ElementType temp = 0;
temp = p->Element;
Q->Front->Next = p->Next;
if ( Q->Rear == p )
Q->Rear = Q->Front;
free( p );
return temp;
}
Error( "Empty queue!!!" );
return 0; /* Return value used to avoid warning */
}
#include <stdio.h>#include "queue_list.h"int main(){ int n, num, m; int i; Queue Q = CreateQueue(); printf( "Initialization complete.\n" ); if ( IsEmpty( Q ) ) printf( "Queue is empty \n" ); printf( "Please input the number of elements in the queue:" ); scanf( "%d", &n ); printf( "Please input %d elements put in queue:", n ); for(i = 0; i < n; i++ ) { scanf( "%d", &num ); Enqueue( num, Q ); } printf( "Front element: %d.\n", Front( Q ) ); printf( "Elements in queue:" ); while ( !IsEmpty( Q )) { printf( "%3d", FrontAndDequeue( Q ) ); } DisposeQueue( Q ); printf( "\n" ); return 0;}
2. 队列的数组实现
文件名:queue_array.h
#ifndef QUEUE_ARRAY_H文件名:queue_array.c
#define QUEUE_ARRAY_H
#define ElementType int
struct QueueRecord;
typedef struct QueueRecord *Queue;
int IsEmpty( Queue Q );
int IsFull( Queue Q );
Queue CreateQueue( int MaxElements );
void DisposeQueue( Queue Q );
void MakeEmpty( Queue Q );
void Enqueue( ElementType X, Queue Q );
ElementType Front( Queue Q );
void Dequeue( Queue Q );
ElementType FrontAndDequeue( Queue Q );
#endif /* QUEUE_ARRAY_H */
#include "queue_array.h"文件名:queue_main.c
#include "fatal.h"
/* Place in implementation file
* Queue implementation is a dynamically allocated array*/
#define MinQueueSize ( 5 )
struct QueueRecord
{
int Capacity;
int Front;
int Rear;
int Size;
ElementType *Array;
};
int
IsEmpty( Queue Q )
{
return Q->Size == 0;
}
void
MakeEmpty( Queue Q )
{
Q->Size = 0;
Q->Front = 1;
Q->Rear = 0;
}
static int
Succ( int value, Queue Q )
{
if ( ++value == Q->Capacity )
value = 0;
return value;
}
void
Enqueue( ElementType X, Queue Q )
{
if( IsFull( Q ) )
Error( "Full queue" );
else
{
Q->Size++;
Q->Rear = Succ( Q->Rear, Q );
Q->Array[ Q-> Rear ] = X;
}
}
void
Dequeue( Queue Q )
{
if ( IsEmpty( Q ) )
Error( "Empty queue" );
else
{
Q->Size--;
Q->Front++;
}
}
ElementType
FrontAndDequeue( Queue Q )
{
ElementType temp = 0;
if ( IsEmpty( Q ) )
Error( "Empty queue" );
else
{
Q->Size--;
temp= Q->Array[ Q->Front ];
Q->Front = Succ( Q->Front, Q );
}
return temp;
}
ElementType
Front( Queue Q )
{
if ( !IsEmpty( Q ) )
return Q->Array[ Q->Front ];
Error( "Empty queue" );
return 0; /* Return value used to avoid warning */
}
int
IsFull( Queue Q )
{
return Q->Size == Q->Capacity;
}
Queue
CreateQueue(int MaxElements )
{
Queue Q;
if ( MaxElements < MinQueueSize )
Error( "Queue size is too small!!!" );
Q = malloc( sizeof( struct QueueRecord ) );
if ( Q == NULL )
FatalError( "Out of space!!!" );
Q->Array = malloc( sizeof( ElementType ) * MaxElements );
if ( Q->Array == NULL )
FatalError( "Out of Space!!!" );
Q->Capacity = MaxElements;
MakeEmpty( Q );
return Q;
}
void
DisposeQueue( Queue Q )
{
if ( Q != NULL )
{
free( Q->Array );
free( Q );
}
}
#include <stdio.h>
#include "queue_array.h"
int
main()
{
int size;
printf( "Please input queue size: " );
scanf( "%d", &size );
Queue Q = CreateQueue( size );
ElementType temp;
printf( "Please input queue elements(seperate by space): " );
while ( !IsFull( Q ) )
{
scanf( "%d", &temp );
Enqueue( temp, Q );
}
printf( "Dequeue queue in turn: " );
while ( !IsEmpty( Q ) )
{
printf( "%3d", FrontAndDequeue( Q ) );
}
printf( "\n" );
DisposeQueue( Q );
return 0;
}
附录:上述代码中用到了Error、FatalError等函数,其实现如下(即fatal.h文件):
#include <stdio.h>
#include <stdlib.h>
#define Error( Str ) FatalError( Str )
#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
备注:本文摘自《数据结构与算法分析 C语言描述 Mark Allen Weiss著》,代码经gcc编译测试通过。
附件下载:http://download.csdn.net/detail/shuxiao9058/4212437#queue-array.tar.gz,http://download.csdn.net/detail/shuxiao9058/4212435#queue-list.tar.gz