数据结构与算法分析-用C语言实现队列(数组方式)

队列先进先出,涉及到两个位置的操作,一个是队首,一个是队尾,我们分别用两个整型变量来表示队首和队尾,另外需要注意的是我们实现队列时要借助循环数组,具体在代码中已经很清楚了。实现过程中的技巧与用数组实现栈时大多数一样。

首先,我们来声明类型,结构和例程。

/**
* @file    Queue.h
* @brief   用链表实现队列-声明ADT部分
* @details
* @author  jason.mrbourne@gmail.com
* @date    2014-5-20
*/
#include <stdio.h>
#ifndef _Queue_h

//实现队列所需的结构和类型
typedef int ElementType;
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);   //出队并返回队首
void FatalError(char *str); //错误信息
static int Succ(int Value, Queue Q);    //队首或队尾的前移
#endif // _Queue_h

然后实现他们:

/**
* @file    Queue.c
* @brief   用链表实现队列-实现部分
* @details
* @author  jason.mrbourne@gmail.com
* @date    2014-5-20
*/
#include <stdlib.h>
#include <Queue.h>
#define MinQueueSize (5)    //最小队列大小
struct QueueRecord
{
    int Front;  //队首
    int Rear;   //队尾
    int Size;   //大小
    int Capacity;   //容量
    ElementType *Array; //队列数组
};

//判断队列是否为空
int IsEmpty(Queue Q)
{
    return Q->Size == 0;
}

//构造空队列
void MakeEmpty(Queue Q)
{
    Q->Size = 0;
    Q->Front = 1;   //初始化队列中队首比队尾大1
    Q->Rear = 0;
}

//错误信息
void FatalError(char *str)
{
    printf("%s", str);
}

//队头或队尾的移动
static int Succ(int Value, Queue Q)
{
    if (++Value == Q->Capacity) //这里用来实现一个循环队列
        Value = 0;
    return Value;
}

//入队
void Enqueue(ElementType X, Queue Q)
{
    if (Q->Size == Q->Capacity)
        FatalError("FUll Queue.");
    else
    {
        ++Q->Size;                      //大小加1
        Q->Rear = Succ(Q->Rear, Q);     //队尾前移
        Q->Array[Q->Rear] = X;          //队尾加入元素
    }

}

//判断队列是否满
int IsFull(Queue Q)
{
    return Q->Size == Q->Capacity;
}

//创建队列
Queue CreateQueue(int MaxElements)
{
    Queue Q;

    if (MaxElements < MinQueueSize)
        FatalError("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);
    }
}

//返回队首元素
ElementType Front(Queue Q)
{
    if(IsEmpty(Q))
        FatalError("Empty Queue");
    else
        return Q->Array[Q->Front];
    return 0;
}

//出队
void Dequeue(Queue Q)
{
    if (IsEmpty(Q))
        FatalError("Empty Queue.");
    else
    {
        Q->Front = Succ(Q->Front, Q);
        Q->Size--;
    }
}

//出队并返回队首
ElementType FrontAndDequeue(Queue Q)
{
    ElementType TmpCell;

    if (IsEmpty(Q))
        FatalError("Empty Queue");
    else
    {
       Q->Size--;
       TmpCell = Q->Array[Q->Front];
       Q->Front = Succ(Q->Front,Q);
       return TmpCell;
    }
    return 0;
}

最后在主程序中测试。

/**
* @file    main.c
* @brief   用链表实现队列-测试部分
* @details
* @author  jason.mrbourne@gmail.com
* @date    2014-5-20
*/
#include <stdio.h>
#include <stdlib.h>
#include <Queue.h>

int main()
{
    //入队3个并依次出队
    Queue Q = CreateQueue(100);
    Enqueue(1,Q);
    Enqueue(2,Q);
    Enqueue(3,Q);
    while (!IsEmpty(Q))
        printf("%d\t", FrontAndDequeue(Q));
}

经过了这几个程序,我们大体上已经掌握了链表,队列和栈的基本实现和常用例程,当然,这只是个基础,对于这几个程序,一个合格的程序员应该做到烂熟于心,关于这几个数据结构的常用应用,我会在后面慢慢来做,下一步,我们就开始学习数据结构中另一个非常重要的部分—排序。


posted @ 2014-05-20 11:27  庄浩  阅读(469)  评论(0编辑  收藏  举报