順序表(動態數組)是線性表最基礎的存儲結構。本文提供一個完整、可編譯運行的 C 實現,包含初始化、尾插、指定位置插入/刪除、查找、遍歷、判空、銷毀等核心操作,並附帶測試主函數與運行結果。
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int length;
} SqList;
SqList* InitList() {
SqList *L = malloc(sizeof(SqList));
if (!L) return NULL;
L->length = 0;
return L;
}
int InsertRear(SqList *L, ElemType e) {
if (L->length >= MAXSIZE) return -1; // 滿
L->data[L->length++] = e;
return 0;
}
int InsertAt(SqList *L, int pos, ElemType e) {
if (L->length >= MAXSIZE || pos < 0 || pos > L->length) return -1;
for (int i = L->length; i > pos; i--) L->data[i] = L->data[i-1]; // 後移
L->data[pos] = e;
L->length++;
return 0;
}
int DeleteAt(SqList *L, int pos, ElemType *e) {
if (L->length == 0 || pos < 0 || pos >= L->length) return -1;
*e = L->data[pos];
for (int i = pos; i < L->length - 1; i++) L->data[i] = L->data[i+1]; // 前移
L->length--;
return 0;
}
int FindByValue(SqList *L, ElemType e) {
for (int i = 0; i < L->length; i++)
if (L->data[i] == e) return i;
return -1;
}
int GetElem(SqList *L, int pos) {
if (pos < 0 || pos >= L->length) return -1;
return L->data[pos];
}
void PrintList(SqList *L) {
if (L->length == 0) { puts("List is empty"); return; }
for (int i = 0; i < L->length; i++) printf("%5d", L->data[i]);
putchar('\n');
}
int IsEmpty(SqList *L) { return L->length == 0; }
void DestroyList(SqList *L) { free(L); }
int main() {
SqList *L = InitList();
int vals[] = {1,2,3,4,5};
for (int v : vals) InsertAt(L, 0, v); // 頭插建表:5 4 3 2 1
PrintList(L);
int tmp;
while (!IsEmpty(L)) {
DeleteAt(L, 0, &tmp);
printf("Deleted: %d\n", tmp);
}
PrintList(L);
DestroyList(L);
return 0;
}
5 4 3 2 1
Deleted: 5
Deleted: 4
Deleted: 3
Deleted: 2
Deleted: 1
List is empty
| 操作 | 平均時間 | 最壞時間 | 空間 |
|---|---|---|---|
| 尾插 | O(1) | O(1) | O(1) |
| 指定位置插入/刪除 | O(n) | O(n) | O(1) |
| 按值查找 | O(n) | O(n) | O(1) |
| 按位查找 | O(1) | O(1) | O(1) |
pos == length(尾後),刪除位置 pos < length;realloc 擴容(倍增策略),而非固定 MAXSIZE;free;void* + size_t 實現泛型順序表。這個順序表實現雖簡單,卻是動態數組、Vector、ArrayList 等高級容器的內核原型。徹底理解它,是掌握數據結構的第一步。