數據結構—隊列的實現(順序表)

數據結構中的隊列有“先進先出”的特點,意思是最先被存進隊列中的數據,總是最先被取走

一個隊列只有初始化,銷燬,入隊列,出隊列和取隊首元素,這些限制往往使在操作數據時更安全,代碼容易實現,出現BUG的機會就很少


上圖隊列,如過進行了多次入隊列和出隊列,就會是head之前的空間浪費,如下圖


爲了避免這種浪費空間的測操作,當每次head 和 tail 只要到達最後一個元素,操作完成就讓他們回到對列的最前面,即head = 0 或 tail = 0,這樣head == taill 時,可能是空對列,也可能是滿對列,所以判斷對列是否滿了出現困難,在對列的機構體中加上一個size成員,用來判斷是否對列已滿

頭文件(SeqQueue.h)

#pragma once

typedef char QueueType;

typedef struct SeqQueue{
    QueueType* place;   //隊列的空間
    size_t head;        //隊首標記
    size_t tail;        //隊尾標記
    size_t size;       //對列當前存儲元素的個數
    size_t max_size;  //對列最大存儲元素個數
}SeqQueue;


void SeqQueueInit(SeqQueue* queue);  //隊列初始化

void DestroyQueue(SeqQueue* queue);    //銷燬隊列

void SeqQueueIn(SeqQueue* queue, QueueType value);    //入隊列

void SeqQueueOut(SeqQueue* queue);    //出隊列

int SeqQueueFront(SeqQueue* queue, QueueType* output_value);     //取隊首元素

頭文件的實現(SeqQueue.c)

#include<stdio.h>
#include<stdlib.h>
#include"SeqQueue.h"

void SeqQueueInit(SeqQueue* queue) {
    queue->max_size = 1;
    queue->size = 0;
    queue->head = 0;
    queue->tail = 0;
    queue->place = malloc(queue->max_size * sizeof(SeqQueue));
    if(queue->place == NULL) {
        printf("malloc 失敗!\n");
        exit(1);
    }
}

void DestroyQueue(SeqQueue* queue) {
    if(queue == NULL) {
        return;
    }
    free(queue->place);
    queue->place = NULL;
    queue->max_size = 0;
    queue->size = 0;
    queue->head = 0;
    queue->tail = 0;
}

void SeqQueueIn(SeqQueue* queue, QueueType value) {
    if(queue == NULL) {
        return;
    }
    if(queue->size >= queue->max_size) {
        queue->max_size = 2 * queue->max_size + 1;
        QueueType* new_place  = malloc(queue->max_size * sizeof(SeqQueue));
        int i = 0;
        if(queue->tail == queue->head) {
            for(i = 0; i < queue->tail; i++) {
                new_place[i] = queue->place[i];
            }
            queue->tail = i;
            for(i = 1; i <= (queue->size - queue->head); i++) {
                new_place[queue->max_size - i] = queue->place[queue->size - i];
            }
            queue->head = queue->max_size - i;
        }
        else if(queue->tail > queue->head) {
            for(i = 0; i < queue->size; i++) {
                new_place[i] = queue->place[i];
            } 
        }
        free(queue->place);
        queue->place = new_place;
    }
    if(queue->tail == queue->max_size) {
        queue->tail = 0;
    }
if(queue->head == queue->max_size) {
        queue->head = 0;
    }
queue->place[queue->tail] = value; queue->tail++; queue->size++;}void SeqQueueOut(SeqQueue* queue) { if(queue == NULL) { return; } if(queue->size == 0) { return; } if(queue->head == queue->max_size) { queue->head = 0; } queue->head++; queue->size--;}int SeqQueueFront(SeqQueue* queue, QueueType* output_value) { if(queue == NULL || output_value == NULL) { *output_value = 0; return 0; } if(queue->size == 0) { *output_value = 0; return 0; }    
*output_value = queue->place[queue->head]; return 1;}/////////////////////////////////////////////////////以下爲測試代碼///////////////////////////////////////////////////void TestQueue() { SeqQueue queue; SeqQueueInit(&queue); SeqQueueIn(&queue, 'a'); SeqQueueIn(&queue, 'b'); SeqQueueIn(&queue, 'c'); SeqQueueIn(&queue, 'd'); int ret; QueueType value; ret = SeqQueueFront(&queue, &value); printf("expected a, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected b, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected c, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected d, actrual %c\n", value); printf("expected 1, actrual %d\n", ret); SeqQueueOut(&queue); ret = SeqQueueFront(&queue, &value); printf("expected 0, actrual %d\n", value); printf("expected 0, actrual %d\n", ret); SeqQueueOut(&queue);}int main(){ TestQueue(); return 0;}

實驗結果



補充:隊列滿了的情況有兩種

第一種:

只需要從舊的空間把head和tail之間的數據對應複製到新的空間

第二種:


把舊0-tail的數據複製到新空間的0-tail

把head到最後一個數據 之間的數據按順序複製到新空間的最後面



發佈了67 篇原創文章 · 獲贊 29 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章