本文主要介紹一下連結串列的特點和使用場景,並且用C語言基於連結串列實現了佇列(FIFO)。
連結串列是一種靈活的資料結構,適合用於需要頻繁插入和刪除操作的場景,但在需要快速隨機訪問的情況下,陣列或其它資料結構可能更為合適。
特點
- 動態大小
連結串列可以根據需要動態增長或縮小,不需要事先定義大小。 - 非連續儲存
連結串列中的節點在記憶體中不必連續儲存,每個節點透過指標連線。 - 插入和刪除效率高
在連結串列中插入或刪除節點的時間複雜度為 O(1),只需調整指標即可,而在陣列中可能需要移動大量元素,時間複雜度為 O(n)。 - 訪問效率低
連結串列的隨機訪問效率較低,要訪問某個節點需要從頭遍歷,時間複雜度為 O(n)。
適用場景 - 實現佇列和棧
連結串列可以方便地實現佇列(FIFO)和棧(LIFO)等資料結構,因為它們需要頻繁的插入和刪除操作。
- 動態資料儲存
當資料量不確定且需要頻繁變化時,連結串列是一種合適的選擇,例如實現動態陣列的替代品。
- 圖和樹的實現
連結串列可用於表示圖的鄰接表和樹的節點結構,方便儲存和遍歷。
- 記憶體管理
在需要頻繁分配和釋放記憶體的應用中,連結串列可以有效管理記憶體,避免記憶體碎片。
使用示例
下面是使用連結串列實現佇列(FIFO)的 C 語言示例程式碼。包括基本的佇列操作,如入隊(enqueue)、出隊(dequeue)。
#include <stdio.h>
#include <stdlib.h>
// 定義連結串列節點
struct Node {
int data;
struct Node* next;
};
// 定義佇列結構
struct Queue {
struct Node* front; // 佇列前端
struct Node* rear; // 佇列後端
};
// 建立新的節點
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化佇列
struct Queue* createQueue() {
struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
queue->front = NULL;
queue->rear = NULL;
return queue;
}
// 入隊操作
void enqueue(struct Queue* queue, int data) {
struct Node* newNode = createNode(data);
if (queue->rear == NULL) {
// 如果佇列為空,前端和後端都指向新節點
queue->front = newNode;
queue->rear = newNode;
} else {
// 否則,將新節點新增到佇列後端
queue->rear->next = newNode;
queue->rear = newNode;
}
printf("%d 入隊\n", data);
}
// 出隊操作
int dequeue(struct Queue* queue) {
if (queue->front == NULL) {
printf("佇列為空,無法出隊\n");
return -1; // 表示佇列為空
}
struct Node* temp = queue->front;
int data = temp->data;
queue->front = queue->front->next;
// 如果佇列變為空,更新後端指標
if (queue->front == NULL) {
queue->rear = NULL;
}
free(temp);
printf("%d 出隊\n", data);
return data;
}
// 列印佇列內容
void printQueue(struct Queue* queue) {
struct Node* current = queue->front;
if (current == NULL) {
printf("佇列為空\n");
return;
}
printf("佇列內容: ");
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
// 主函式
int main() {
struct Queue* queue = createQueue();
enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);
printQueue(queue);
dequeue(queue);
printQueue(queue);
dequeue(queue);
printQueue(queue);
dequeue(queue);
printQueue(queue);
dequeue(queue); // 嘗試從空佇列出隊
// 釋放佇列記憶體(可選)
free(queue);
return 0;
}
程式碼邏輯比較清晰,就不做過多解釋了。