队列

来源:互联网 发布:程序员写文档的工具 编辑:程序博客网 时间:2024/06/03 14:45

队列

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

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

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

一 队列的静态顺序存储

#define  MAX_QUEUE_SIZE   100typedef  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;    }}
原创粉丝点击