線性表 是由 n 個屬於 同一數據對象 的數據元素組成的 有限 序列。除序列的第一個數據元素與最後一個數據元素以外,其餘任何一個數據元素有且僅有一個直接前驅元素,有且僅有一個直接後繼元素。數組
線性表的存儲結構能夠採用 順序存儲結構 和 鏈式存儲結構,採用順序存儲結構的線性表又稱爲 順序表。bash
只要肯定了首地址,線性表中任意一個數據元素能夠隨機存取。所以,能夠稱線性表的存儲結構爲一種隨機存取的存儲結構。優化
書中介紹了順序表的幾種常見操做,本文嘗試用完整 C 語言實現。ui
編寫 util.h
頭文件,定義 ERRORMESSAGE
,須要拋出異常時打印 log 並退出。在順序表的實現中,ElemType
爲 int
。spa
#include <stdio.h>
#include <stdlib.h>
#define ERRORMESSAGE(msg) \ { \ printf(msg); \ exit(1); \ }
typedef int ElemType;
複製代碼
編寫 02-list.c
文件,是順序表的實現文件。code
// 引入 util 頭文件
#include "util.h"
// 假設順序表最多存放 100 個數據元素
#define MaxSize 100
// 聲明順序表(使用數組實現)
ElemType A[MaxSize];
// 順序表實際存儲元素數量
int n = 0;
複製代碼
書中的定義是第 i
個位置,下同,也就是說參數是從 1 開始的。順序表的插入操做時間複雜度爲 O(n)
。對象
/** * 在長度爲 n 的線性表 A 的第 i 個位置插入一個新數據元素 item */
void insertList(ElemType A[], int *n, int i, ElemType item) {
if (*n == MaxSize || i < 1 || i > *n + 1) {
ERRORMESSAGE("表滿或插入位置不正確!");
}
for (int j = *n - 1; j >= i - 1; j--) {
A[j + 1] = A[j];
}
A[i - 1] = item;
(*n)++;
}
複製代碼
時間複雜度爲 O(n)
。string
/** * 刪除長度爲 n 的線性表 A 的第 i 個數據元素 */
void deleteList(ElemType A[], int *n, int i) {
int j;
if (i < 1 || i > *n) {
ERRORMESSAGE("表滿或刪除位置不正確!");
}
for (j = i; j < *n; j++) {
A[j - 1] = A[j];
}
(*n)--;
}
複製代碼
時間複雜度爲 O(n)
。it
/** * 肯定元素 item 在長度爲 n 的線性表 A 中的位置 */
int locate(ElemType A[], int n, ElemType item) {
for (int i = 0; i < n; i++) {
if (A[i] == item) {
return i + 1;
}
}
return -1;
}
複製代碼
時間複雜度爲 O(n^2)
。io
/** * 刪除表中重複出現的元素 */
void purge(ElemType A[], int *n) {
int i = 0, j;
while (i < *n) {
j = i + 1;
while (j < *n) {
if (A[j] == A[i]) {
deleteList(A, n, j + 1);
} else {
j++;
}
}
i++;
}
}
複製代碼
通常的實現方式是先遍歷查找,若是找到了進行刪除操做,時間複雜度爲 O(n^2)
。
優化版的時間複雜度爲 O(n)
,由於只須要記錄符合條件(須要被刪除)的個數,一遍遍歷便可完成操做。
/** * 基礎版 */
void deleteItem(ElemType A[], int *n, ElemType item) {
int i = 0;
while (i < *n) {
if (A[i] == item) {
deleteList(A, n, i + 1);
} else {
i++;
}
}
}
/** * 優化版 */
void deleteItem2(ElemType A[], int *n, ElemType item) {
int k = 0;
for (int i = 0; i < *n; i++) {
if (A[i] == item) {
k++;
} else {
A[i - k] = A[i];
}
}
*n = *n - k;
}
複製代碼
void printList(ElemType A[], int *n) {
for (int i = 0; i < *n; i++) {
printf("%d", A[i]);
}
printf("\n");
}
複製代碼