数据结构:队列(一)

                    图一:线性队列                                           图二:环形队列

一、线性队列和环形队列的比较

我们通常在使用队列的时候,在线性和环形两者之中,我们通常会选择环形,并且在书中,我们也最常见的是环形队列,有没有想过这是为什么呢?接下来就让我们来谈谈why和how。

这个算法效率高不高,我们通常会考虑它的时间复杂度,在线性队列中,入队和出队的时间复杂度分别为O(1)和O(n),而环形队列又可以说成顺序表是环形的,实际是用顺序表实现环形队列。它的入队和出队时间复杂度均为O(1),所以环形的目的是为了提高出队的时间复杂度。细心的同学会发现,在图二中浪费了一个单元不使用,这是为了区分队空和队满。在下面的代码中会提到。

二、深入了解环形队列

front队头:第一个元素的下标

rear队尾:最后一个元素的下一个下标

队满:(rear+1)%n==front  {可以与魔方阵的算法思想联系起来}

队空:  front==rear

首先,我们要学会定义一个结构体,这个环形队列中就包括了数据,front,rear

#define SIZE 10

typedef struct SQueue
{
    int elem[SIZE];
    int front;//队头指针,第一个元素的下标
    int rear;//队尾指针,最后一个元素的下一个下标,当前可以存放数据的下标
}SQueue,*PSQueue;

//初始化

void InitQueue(PSQueue ps)

{
    assert(ps != NULL);
    if(ps == NULL)
    {
    return ;
    }
    ps->front = 0;
    ps->rear = 0;
}

//判满

static bool IsFull(PSQueue ps)
{
    return (ps->rear+1)%SIZE == ps->front;//
}
//入队
bool Push(PSQueue ps,int val)
{
    if(IsFull(ps))
    {
    return false;
    }
    ps->elem[ps->rear] = val;
    ps->rear = (ps->rear+1)%SIZE;

    return true;
}

//获取队头的值,但不删除
bool GetTop(PSQueue ps,int *rtval)
{
    if(IsEmpty(ps))
    {
    return false;
    }
    if(rtval != NULL)
    {
    *rtval = ps->elem[ps->front];
    }

    return true;
}

//获取队头的值,且删除
bool Pop(PSQueue ps,int *rtval)

{
    if(IsEmpty(ps))
    {
    return false;
    }
    if(rtval != NULL)
    {
    *rtval = ps->elem[ps->front];
    }

    int *p=ps->front;

    ps->front=p->front;

    free(p);

    return true;
}

//判断队空
bool IsEmpty(PSQueue ps)

{

    return front==rear;

}


 


 

猜你喜欢

转载自blog.csdn.net/qq_41896788/article/details/83796831