數據結構-隊列

隊列(Queue)

也是一種限制存取點的線性表c++

隊首和隊尾

  • 隊首: 隊列容許進行刪除操做的一端
  • 隊尾: 隊列容許進行插入操做的一端

隊列的特性

先入先出web

隊列的存儲結構

  1. 順序存儲結構: 順序隊
  2. 鏈式存儲結構: 鏈隊

順序隊

  1. 結構定義:數組

    typedef struct{
       ElemType data[MAX_SIZE]; //順序存儲
       int front;               //隊首指針
       int rear;                //隊尾指針
    }SqQueue;
  2. 特色:數據結構

    • 同其它靜態分配的順序存儲結構同樣, 容量有限
    • 在兩端均可以進行操做(一邊插入, 一邊刪除)
    • 指針移動是同向的, 因此frontrear都有可能到達數組末端
  3. 假溢出:svg

    frontrear 都到達數組末端時, 這時隊列爲空, 可是不能插入元素, 稱爲假溢出, 會下降存儲空間利用率ui

  4. 循環隊列解決假溢出:spa

    利用取模操做% , 當front或者rear 指針到達數組末端時可以繼續移動到數組首部, 這樣就能繼續使用數組空間, 這種數據結構稱爲循環隊列指針

    eg: code

    rear = MAX_SIZE - 1;
    rear = (rear + 1) % MAX_SIZE;
    /*
    *rear = 0, 移動到數組首部
    */

  5. 操做集:xml

    /* * 這裏使用front指向隊首元素, rear指向隊尾元素的下一個位置 * front和rear不一樣指向都有差別, 這裏只是一種 */
    
    //隊列大小(手畫一下循環隊列就明白了), 注意取模
    //這裏可以得出隊列爲空時, front = rear
    //隊列滿時, (rear + 1) % MAX_SIZE = front, 此時有一個空間沒有存儲元素, 最大size是MAX_SIZE - 1
    int size(SqQueue sq){
       return (sq.rear - sq.front + MAX_SIZE) % MAX_SIZE;
    }
    
    //判空
    int isEmpty(SqQueue sq){
       return size(sq) == 0;//或者寫成sq.front == sq.rear
    }
    
    int isFull(SqQueue sq){
       return sq.size() == MAX_SIZE - 1;//或者寫成(sq.rear + 1) % MAX_SIZE == sq.front
    }
    
    Status push(SqQueue &sq, ElemType x){
       if(isFull(sq)) return ERROR; //隊列已滿
       sq.data[sq.rear] = x;
       sq.rear = (sq.rear + 1) % MAX_SIZE;
       return OK;
    }
    
    Status pop(SqQueue &sq, ElemType &x){
       if(isEmpty(sq)) return ERROR;//隊列爲空
       x = sq.data[sq.front];
       sq.front = (sq.front + 1) % MAX_SIZE;
       return OK;
    }
    
    Status top(SqQueue sq, ElemType &x){
       if(isEmpty(sq)) return ERROR;
       x = sq.data[sq.front];
       return OK;
    }

鏈隊

  1. 結構定義:

    typedef struct LNode{
       ElemType data;
       struct LNode * next;
    }LNode;//結點
    
    typedef struct {
       LNode * front;
       LNode * rear;
    }LinkQueue;//front指向隊首, rear指向隊尾
  2. 操做集:

    LNode * newNode(ElemType x){
       LNode * res = (LNode *)malloc(sizeof(LNode));
       res->data = x;
       res->next = NULL;
    }
    //隊爲空時頭結點的front和rear都爲空
    int isEmpty(LinkQueue lq){
       return lq.front == NULL;//或者是lq.rear == NULL
    }
    
    void push(LinkQueue &lq, ElemType x){
       LNode * tmp = newNode(x);
       if(isEmpty(lq)){        //空隊列
           lq.front = lq.rear = tmp;
           return;
       }
       //尾插法
       lq.rear->next = tmp;
       lq.rear = tmp;
    }
    
    Status pop(LinkQueue &lq, ElemType &x){
       if(isEmpty(lq)) return ERROR;
       LNode * tmp = lq.front;
       if(tmp->next == NULL) lq.front = lq.rear = NULL;
       else lq.front->next = tmp->next;
       x = tmp->data;
       free(tmp);
       return OK;
    }
    
    Status front(LinkQueue lq, ElemType &x){
       if(isEmpty(lq)) return ERROR;
       x = lq.front->data;
       return OK;
    }
  3. 特色:

    • 無容量限制
    • 插入刪除時frontrear 均可能修改