顺序表示
需熟练掌握顺序表的定义,并且能够用手写代码实现顺序表上的各种操作。
顺序表定义
顺序表(Sequential List) 是一种常见的数据结构,用于存储一组元素,并按照它们在内存中的物理顺序来排列和访问这些元素。顺序表通常由一个数组或列表构成,其中每个元素都占据一个连续的内存位置,并且可以通过索引值来访问。
假设线性表 A 存储的其实位置为LOC(A)
,每个元素占用的存储空间的大小为sizeof(Elem)
,则 A 所对应的顺序存储结构为:
- 顺序表 优点:
- 随机访问性强:顺序表支持通过索引直接访问元素,访问速度快,时间复杂度为O(1)。
- 空间使用连续:顺序表中的元素存储在连续的内存块中,这有助于提高缓存的局部性,从而提高访问速度。
- 操作简单:无需处理复杂的指针操作。
- 顺序表 缺点:
- 固定大小或调整大小的开销:对于静态数组,大小是固定的,如果预分配的空间不足或过大,会导致内存浪费或数组溢出。动态数组可以重新分配大小,但这会增加时间和空间开销。
- 插入和删除的时间开销:如果要在顺序表的中间插入或删除元素,可能需要移动大量的元素,时间复杂度为O(n)。
操作
#define MAXSIZE 100
typedef struct {
ElementType data[MAXSIZE];
int length;
} SeqList;
void InitList(SeqList *L) {
L->length = 0;
}
bool Insert(SeqList *L, int pos, ElementType e) {
if (L->length == MAXSIZE || pos < 1 || pos > L->length + 1) {
return false;
}
for (int i = L->length; i >= pos; i--) {
L->data[i] = L->data[i - 1];
}
L->data[pos - 1] = e;
L->length++;
return true;
}
bool Delete(SeqList *L, int pos, ElementType *e) {
if (pos < 1 || pos > L->length) {
return false;
}
*e = L->data[pos - 1];
for (int i = pos; i < L->length; i++) {
L->data[i - 1] = L->data[i];
}
L->length--;
return true;
}
int LocateElem(SeqList L, ElementType e) {
for (int i = 0; i < L.length; i++) {
if (L.data[i] == e) {
return i + 1; // 返回元素位置,而不是下标
}
}
return 0; // 未找到返回0
}
bool GetElem(SeqList L, int pos, ElementType *e) {
if (pos < 1 || pos > L.length) {
return false;
}
*e = L.data[pos - 1];
return true;
}
bool IsEmpty(SeqList L) {
return L.length == 0;
}
void ClearList(SeqList *L) {
L->length = 0;
}
int Length(SeqList L) {
return L.length;
}