佇列

Cazkeen發表於2020-12-01

示例圖:


定義:只能在表的一端進行插入運算,在表的另一端進行刪除運算的線性表 (頭刪尾插)

儲存結構:順序隊,鏈隊

運算規則:先進先出(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;
}




相關文章