數據結構之隊列(C語言實現)

Table of Contents

定義

實現

定義結構

定義操作創建隊列

訪問隊首元素

出隊

入隊


定義

在棧中提到,隊列是操作受限制的特殊的線性表。
在隊列的一端只能插入元素,這一端叫做隊尾。
在隊列的另一端只能刪除元素,這一端叫做隊首。

舉個栗子,在食堂排隊打飯,跑的快的同學排在隊列的前面,最先打到飯菜。後續到的同學只能依次排列在隊尾。買到飯菜的同學離開隊列叫做出隊,進入隊列等候叫做入隊。食堂阿姨給隊列中第一個同學打飯叫做訪問隊首元素。

總結:隊列有先進先出的特性,FIFO(First In First Out)。每次只能在線性表的兩端操作元素。

實現

考慮到每次出隊和入隊都要移動隊首和隊尾指針。若採用順序存儲,將會有可能造成順序表前段部分存儲單元的浪費。雖說可以採用循環隊列的方式複用存儲單元,若遇到隊列滿的情況,將隊列擴容比較麻煩。因此建議用鏈表的方式實現隊列。

定義結構

typedef int QueueType;

struct LinkQueue{
    QueueType key;
    struct LinkQueue *next;
};

typedef struct queueNode{
    struct LinkQueue *head;//隊列的頭指針
    struct LinkQueue *end;//隊列的尾指針
}Queue;


這裏定義了連個結構體,鏈表和隊列。隊列中只保存兩個指針——隊首、隊尾。後面的入隊、出隊的操作,只需要操作這兩個指針就好。

定義操作
創建隊列

/**
 * 創建隊列
 */
Queue createQueue() {
    Queue queue;
    queue.head = 0;
    queue.end = 0;
    return queue;
}

採用靜態方式分配隊列存儲單元。初始化隊首和隊尾指針。

判斷隊列是否爲空

/**
 * 判斷隊列是否是空
 */
int isEmpty(Queue queue) {
    if (queue.head == 0)
        return 0;
    else
        return 1;
}

隊首指針指向空結點,表示隊列爲空。

訪問隊首元素

/**
 * 獲取隊列第一個元素
 */
int getFirst(Queue queue, QueueType& elem) {
    if (queue.head == 0)
        return 0;
    elem = queue.head->key;
    return 1;
}

隊首指針可作爲鏈表的頭結點。通過頭結點訪問鏈表的第一個結點。

出隊

/**
 * 退出隊列
 */
int exitQueue(Queue& queue, QueueType& val) {
    if (isEmpty(queue) == 0) //空隊列
        return 0;
    struct LinkQueue* node = queue.head;
    queue.head = node->next;
    node->next = 0;
    val = node->key;
    free(node);
    if (queue.head == 0)
        queue.end = 0;
    return 1;
}

通過隊首指針,刪除隊列第一個結點。如果刪除後隊列爲空,將隊尾指針置空,否則隊尾指針仍然指向最後一個元素。隊列爲空,刪除失敗,返回0 。刪除成功返回1。

入隊

/**
 * 進入隊列
 */
int enterQueue(Queue& queue, QueueType key) {
    struct LinkQueue* node = (struct LinkQueue*) malloc(
            sizeof(struct LinkQueue));
    if (node == NULL)
        return 0;
    node->key = key;
    node->next = 0;
    if (queue.end == 0) {
        queue.end = node;
    } else {//修改隊尾指針
        queue.end->next = node;
        queue.end = node;
    }
    if (queue.head == 0) {
        queue.head = node;
    }
    return 1;
}

隊列爲空時,隊首和隊尾指針指向同一個結點就好。隊列不爲空時,修改隊尾指針指向新插入的結點。入隊成功返回1,入隊失敗返回0。

最後附上頭文件的定義

/*
 * queue.h
 *
 *  Created on: 2016年9月30日
 *      Author: flueky
 */

#ifndef QUEUE_H_
#define QUEUE_H_

typedef int QueueType;

struct LinkQueue {
    QueueType key;
    struct LinkQueue *next;
};

typedef struct queueNode {
    struct LinkQueue *head; //隊列的頭指針
    struct LinkQueue *end; //隊列的尾指針
} Queue;

/**
 * 創建隊列
 */
Queue createQueue();

/**
 * 判斷隊列是否是空
 */
int isEmpty(Queue);

/**
 * 獲取隊列第一個元素
 */
int getFirst(Queue, QueueType&);

/**
 * 進入隊列
 */
int enterQueue(Queue&, QueueType);
/**
 * 退出隊列
 */
int exitQueue(Queue&, QueueType&);

/**
 * 清空隊列
 */
void clearQueue(Queue);

#endif /* QUEUE_H_ */

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章