队列

队列

队列(Queue):是运算受限的线性表。是一种先进先出(First In First Out ,简称FIFO)的线性表。只允许在表的一端进行插入,而在另一端进行删除。

队首(front) :允许进行删除的一端称为队首。

队尾(rear) :允许进行插入的一端称为队尾。

一 队列的静态顺序存储

#define  MAX_QUEUE_SIZE   100
typedef  struct  queue{
   ElemType   Queue_array[MAX_QUEUE_SIZE] ;
   int        front ;
   int        rear ;
}SqQueue;

        顺序队列中存在“假溢出”现象。因为在入队和出队操作中,头、尾指针只增加不减小,致使被删除元素的空间永远无法重新利用。因此,尽管队列中实际元素个数可能远远小于数组大小,但可能由于尾指针巳超出向量空间的上界而不能做入队操作。该现象称为假溢出。

1.1 循环队列

        为充分利用向量空间,克服上述“假溢出”现象的方法是:将为队列分配的向量空间看成为一个首尾相接的圆环,并称这种队列为循环队列(Circular Queue)。

  • 循环队列为空:front=rear;
  • 循环队列满:(rear+1)%MAX_QUEUE_SIZE =front;
1.1.1 循环队列的初始化
SqQueue Init_CirQueue(void)
{
    SqQueue  Q;
    Q.front = Q.rear = 0;
    return Q;
}
1.1.2 入队操作
/*  将数据元素e插入到循环队列Q的队尾  */
Status Insert_CirQueue(SqQueue Q, ElemType e)
{
    if((Q.rear+1)%MAX_QUEUE_SIZE== Q.front)
        return  ERROR;                   //队满,返回错误标志
    Q.Queue_array[Q.rear]=e;             //元素e入队
    Q.rear=(Q.rear+1)% MAX_QUEUE_SIZE;   //队尾指针向前移动
    return OK;                           //入队成功
}
1.1.3 出队操作
/*将循环队列Q的队首元素出队*/
Status Delete_CirQueue(SqQueue  Q, ElemType  *x )
{
    if(Q.front == Q.rear)
        return ERROR ;                    //队空,返回错误标志
    *x=Q.Queue_array[Q.front] ;           //取队首元素
    Q.front=(Q.front+1)% MAX_QUEUE_SIZE ; //队首指针向前移动
    return OK ;
}

二 队列的链式存储

数据元素结点:

typedef struct Qnode{
    ElemType       data;
    struct Qnode  *next;
}QNode;

指针结点类型:

typedef struct link_queue
{
    QNode *front, *rear;
}Link_Queue;

2.1 链队列的初始化

LinkQueue *Init_LinkQueue(void)
{
    LinkQueue *Q;
    QNode     *p;
    p=(QNode *)malloc(sizeof(QNode));          //开辟头结点
    p->next=NULL;
    Q=(LinkQueue *)malloc(sizeof(LinkQueue)); //开辟链队的指针结点
    Q.front = Q.rear = p; 
    return Q;
}

2.2 链队列的入队操作

/* 将数据元素e插入到链队列Q的队尾 */
Status  Insert_CirQueue(LinkQueue *Q, ElemType e)
{
    p=(QNode *)malloc(sizeof(QNode));
    if (!p)
        return  ERROR;  //申请新结点失败,返回错误标志
    p->data=e;
    p->next=NULL;       //形成新结点
    Q.rear->next=p ;
    Q.rear=p ;          //新结点插入到队尾
    return OK;
}

2.3 链队列的出队操作

Status Delete_LinkQueue(LinkQueue *Q, ElemType *x)
{
    QNode *p ;
    if(Q.front==Q.rear)
        return ERROR;            //队空
    p=Q.front->next ;            //取队首结点
    *x=p->data ; 
    Q.front->next = p->next ;   //修改队首指针
    if(p==Q.rear)
        Q.rear=Q.front;         //当队列只有一个结点时应防止丢失队尾指针
    free(p);   
    return OK; 
}

2.4 链队列的撤消

/* 将链队列Q的队首元素出队 */
void  Destroy_LinkQueue(LinkQueue *Q )
{
    while(Q.front!=NULL)
    {
        Q.rear = Q.front->next; //令尾指针指向队列的第一个结点
        free(Q.front);          //每次释放一个结点 
                                //第一次是头结点,以后是元素结点  */
        Q.front = Q.rear;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值