一、概述:
像栈一样,队列(queue)也是表。然而,使用队列时插入在一端进行而删除在另一端进行。
队列的基本操作是Enqueue(入队),它是在表的末端(叫做队尾(rear)插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(叫做队头(front)的元素。如图1所示显示一个队列的抽象模型。
图1 队列模型
二、实现
如同栈的情形一样,对于队列而言任何表的实现都是合法的。像栈一样,对于每一种操作,链表实现和数组实现都给出快速的
O(1)运行时间。
1. 队列的链表实现
文件名:queue_list.h
- #ifndef _QUEUE_LIST_H
- #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"
- #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
- #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"
- #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 )