队列 - C语言实现(摘自数据结构与算法分析 C语言描述)

时间:2022-04-18 11:09:34

一、概述:

像栈一样,队列(queue)也是表。然而,使用队列时插入在一端进行而删除在另一端进行。

队列的基本操作是Enqueue(入队),它是在表的末端(叫做队尾(rear)插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(叫做队头(front)的元素。如图1所示显示一个队列的抽象模型。

队列 - C语言实现(摘自数据结构与算法分析 C语言描述)

图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 */
文件名:queue_list.c
#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 */
}
文件名:queue_list_main.c
#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 */
文件名:queue_array.c
#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 );
}
}
文件名:queue_main.c
#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