队列

示例图:


定义:只能在表的一端进行插入运算,在表的另一端进行删除运算的线性表 (头删尾插)

存储结构:顺序队,链队

运算规则:先进先出(FIFO)


一:链式队列:

 1.存储结构定义:

typedef struct  Qnode {
  QElemType    data;
  stuct  Qnode  *next;
}QNode, *QuenePtr;

typedef struct {
  QuenePtr front; // 队头指针
  QuenePtr rear; // 队尾指针
} LinkQueue; 
2.基本操作:

 (1)初始化链对:

Status InitQueue(LinkQueue &q) { //构造空队列q
 q.front = q.rear =(QueuePtr)malloc(sizeof(QNode));//队头和队尾指向同一个区域
 If (!q.front) exit (OVERFLOW); //存储分配失败
 q.front ->next = NULL;//队头指向的区域为空
 return OK;
}// InitQueue;
(2)销毁队列

Status DestoryQueue(LinkQueue &q) { //销毁队列q
   while (q.front) 
       {  
           q.rear = q.front -> next;//用q.rear(QuenePtr类型),节省空间
           free(q.front);//释放结点
           q.front = q.rear;//转移队头指针
       }
   return OK;
}// DestoryQueue;
(3)入队:

status EnQueue(LinkQueue &Q,ElemType e)
{
   p=(QueuePtr)molloc(sizeof(QNode));
   if(!p)exit(OVERFLOW);
   p->data=e;
   p->next=null;
   Q.rear->next=p;
   Q.rear=p;
   return OK;
}
(4)出队(删除队头元素(头结点连接的第一个元素)):

status EnQueue(LinkQueue &Q,EleType &e)
{
   if(Q.front==Q.rear)return ERROR;
   p=Q.font->next;
   e=p.data;
   Q.font->next=p->next;
   if(p==Q.rear)Q.rear=Q.front;//链队中只有一个元素(还有一个头结点)的情况
   free(p);//释放p结点
   return OK;
}


二.队列的顺序表示:

1.存储结构类型定义:

Struct Queue
{   
   ElemType queue[QueueMaxSize];  
   int front,rear;
};
    *队头Q.front总是指向元素,队尾Q.rear总是指向要增加的元素

2.顺序队列可能会遇到下面问题(如图所示):


队满可能会有几种形式:

      1).队中有全部元素

      2).队中只有上半部分有元素

      3).队中没有元素

假上溢:队空间中还有存储单元未使用,但不能再插入元素。

假上溢产生原因:头、尾指针值总是不断改变,导致已使用过的单元无法再使用。

3.可采用以下方式解决:

  (1).元素都往队头靠(缺点:浪费时间)

  (2).采用循环队列(详解如三)


三.循环队列:

1.存储结构定义:

typedef struct {
  QElemType *base; // 动态分配存储空间
  int front; 
      // 头指针,若队列不空,指向队列头元素
  int rear;  
      // 尾指针,若队列不空,指向队列尾元素
         的下一个位置
  } SqQueue; 
2.存在的问题及解决手段:

    这样设计之后也存在问题,当队空时,有Q.front=Q.rear;而队满时也是Q.front=Q.rear,故造成冲突

    解决方法:

            1).在队中设立一个空的存储单元,这样的话队满时就是Q.front=(Q.rear+1)%MaxSize

            2).增加一个标志量Q.flag,当初始化循环队列时(队空),Q.flag=0;当有元素且Q.front=Q.rear时

            3).设置一个标志量用来记录元素的个数,当元素个数为0为队空,当元素个数等于MaxSize时队满

3.基本操作:

(1)初始化空队列:

Status InitQueue(SqQueue &Q) { //构造空队列Q
  q.base = (QElemType*) malloc(MAXSIZE*sizeof(QElemType));
  If (!q.base) exit (OVERFLOW); //存储分配失败
  q.front = q.rear = 0;
  return OK;
}//InitQueue;

(2)求队列的长度:

Int QueueLen(SqQueue Q)  
{
    //求取队列Q的元素个数
    return (Q.rear - Q.front + MAXSIZE) % MAXSIZE; 
}

(3)入队:

Status InsertQueueLen(SqQueue &Q,QElemType e){
//元素e入队列Q
 if ((Q.rear + 1) % MAXSIZE == Q.front)//如果队满,则就不能入队
     return ERROR;
 Q.base[Q.rear] = e;
 Q.rear = (Q.rear + 1) % MAXSIZE;
 return OK;
}

(4).出队:

int DeQueue ( SeqQueue &Q, QElemType &e ) {
   if ( QueueEmpty (Q) ) return 0;		
 	 e = Q.base[Q.front]; 
	 Q.front = ( Q.front+1) % MAXQSIZE;
	 return OK;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值