順序表是線性表最基礎的儲存結構,採用連續記憶體空間(陣列)依序存放資料元素,邏輯上相鄰的元素在物理位置上也相鄰。特點是隨機存取 O(1)、插入刪除需移動元素 O(n),適合「查多改少」的場景。
#define MAXSIZE 20
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SeqList;
data:固定大小陣列,儲存元素;length:當前有效元素個數,區別於陣列容量 MAXSIZE。void InitList(SeqList *L) { L->length = 0; }
void ClearList(SeqList *L) { L->length = 0; }
bool ListEmpty(SeqList L) { return L.length == 0; }
int ListLength(SeqList *L) { return L->length; }
ListInsert(L, i, e)在第 i 個位置(1-based)插入元素 e,需檢查滿溢與索引合法性,並將 i 及之後元素後移。
bool ListInsert(SeqList *L, int i, ElemType e) {
if (L->length >= MAXSIZE) return false; // 滿
if (i < 1 || i > L->length + 1) return false; // 索引非法
for (int j = L->length; j >= i; j--)
L->data[j] = L->data[j-1]; // 後移
L->data[i-1] = e;
L->length++;
return true;
}
ListDelete(L, i, &e)刪除第 i 個元素並以 e 返回,前移後續元素填補空缺。
bool ListDelete(SeqList *L, int i, ElemType *e) {
if (i < 1 || i > L->length) return false;
*e = L->data[i-1];
for (int j = i; j < L->length; j++)
L->data[j-1] = L->data[j];
L->length--;
return true;
}
GetElem 與 按值查找 LocateElembool GetElem(SeqList *L, int i, ElemType *e) {
if (i < 1 || i > L->length) return false;
*e = L->data[i-1];
return true;
}
int LocateElem(SeqList *L, ElemType e) { // 返回 1-based 位置,0 表未找到
for (int i = 0; i < L->length; i++)
if (L->data[i] == e) return i+1;
return 0;
}
UnionList將 ListB 中不存在於 ListA 的元素插入 ListA 尾部。
void UnionList(SeqList *LA, SeqList LB) {
for (int i = 0; i < LB.length; i++)
if (!LocateElem(LA, LB.data[i]))
ListInsert(LA, ++LA->length, LB.data[i]);
}
void ShowList(SeqList L) {
printf("[ ");
for (int i = 0; i < L.length; i++) printf("%d ", L.data[i]);
printf("]\n");
}
int main() {
SeqList L, LB; ElemType r;
InitList(&L); InitList(&LB);
// 建立測試資料
ListInsert(&L,1,1); ListInsert(&L,2,2); ListInsert(&L,3,3); ListInsert(&L,4,4);
ListInsert(&L,2,5); ShowList(L); // [ 1 5 2 3 4 ]
ListDelete(&L,4,&r); ShowList(L); // 刪除第4個(3) → [ 1 5 2 4 ]
GetElem(&L,2,&r); printf("GetElem 2: %d\n", r); // 5
printf("Locate 5=%d, Locate 3=%d\n", LocateElem(&L,5), LocateElem(&L,3));
// 合併測試
ListInsert(&LB,1,3); ListInsert(&LB,2,5); ListInsert(&LB,3,37);
ListInsert(&LB,4,4); ListInsert(&LB,2,9); ListInsert(&LB,5,109);
ListInsert(&LB,3,2); ListDelete(&LB,4,&r);
UnionList(&L, LB); ShowList(L); // 合併後結果
return 0;
}
| 操作 | 時間複雜度 | 說明 |
|---|---|---|
| 隨機存取 | O(1) | 優勢:直接下標定位 |
| 插入/刪除 | O(n) | 劣勢:需大量移動元素 |
| 空間利用 | 固定 | 靜態分配易溢出或浪費 |
順序表適合資料量固定、頻繁隨機讀取、較少插刪的場景(如查字典、靜態查表)。動態擴容版本(C++ vector、Java ArrayList)透過倍增策略將攤還插入複雜度降至 O(1),是現代語言標準庫的預設動態陣列實作。
i-1;length+1(尾插),刪除上限為 length;#define MAXSIZE,實務請改動態分配 malloc/realloc。順序表是資料結構入門的基石,掌握其連續儲存特性、插刪移動機制、靜態與動態版本差異,能為後續學習鏈表、樹、圖等非連續結構建立鮮明對比認知。實作時務必注意邊界條件與記憶體管理,養成防禦性程式設計習慣。