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

一、概述:

像栈一样,队列(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 */
文件名: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

你可能感兴趣的:(数据结构,c,算法,struct,null,语言)