顺序表(Sequential List)的完整实现与详解~

星隐

一、引言

顺序表是线性表的顺序存储实现,是数据结构中最基础也是最重要的线性结构之一。本文将详细解析一个完整的顺序表实现,包括基本操作、扩展功能以及交互式菜单系统。

二、基础定义与结构设计

2.1 常量与类型定义

1
2
3
4
5
6
7
8
#define MAXSIZE 100 // 最大容量
#define ERROR 0
#define OK 1
#define OVERFLOW (-1)
#include <iostream>
#include <cstdlib>
using namespace std;
typedef int Status;

设计说明:

  • MAXSIZE:定义顺序表的最大容量为100个元素
  • Status:函数返回状态类型,用于表示操作成功或失败
  • 返回值约定:OK表示成功,ERROR表示失败,OVERFLOW表示内存溢出

2.2 顺序表结构体

1
2
3
4
5
6
typedef struct
{
int *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量
} SqList;

结构成员解析:

  • elem:指向动态分配的数组首地址
  • length:当前顺序表中元素的个数
  • listsize:当前分配的存储容量(最大可存储元素数)

三、核心基础操作

3.1 初始化顺序表

1
2
3
4
5
6
7
8
9
10
Status InitList(SqList &L)
{
L.elem = new int[MAXSIZE];
if (!L.elem)
return OVERFLOW;
L.length = 0;
L.listsize = MAXSIZE;
cout << "顺序表初始化成功!" << endl;
return OK;
}

功能说明:

  • 动态分配MAXSIZE大小的内存空间
  • 检查内存分配是否成功
  • 初始化长度为0,容量为MAXSIZE

3.2 销毁顺序表

1
2
3
4
5
6
7
8
9
10
void DestroyList(SqList &L)
{
if (L.elem)
{
delete[] L.elem;
L.elem = NULL;
L.length = 0;
L.listsize = 0;
}
}

功能说明:

  • 释放动态分配的内存
  • 将指针置空,防止野指针
  • 重置长度和容量为0

3.3 清空顺序表

1
2
3
4
5
void ClearList(SqList &L)
{
L.length = 0;
cout << "顺序表已清空!" << endl;
}

功能说明:

  • 仅将长度置0,不释放内存空间
  • 逻辑清空,物理空间保留

3.4 判断空表

1
2
3
4
bool ListEmpty(SqList L)
{
return L.length == 0;
}

3.5 获取长度

1
2
3
4
int ListLength(SqList L)
{
return L.length;
}

四、数据访问操作

4.1 按位置获取元素

1
2
3
4
5
6
7
Status GetElem(SqList L, int i, int &e)
{
if (i < 1 || i > L.length)
return ERROR;
e = L.elem[i - 1];
return OK;
}

算法分析:

  • 时间复杂度:O(1)
  • 注意:位序从1开始,数组下标从0开始
  • 边界检查:确保i在合法范围内

4.2 按值查找元素

1
2
3
4
5
6
7
8
9
int LocateElem(SqList L, int e)
{
for (int i = 0; i < L.length; i++)
{
if (L.elem[i] == e)
return i + 1; // 返回位序(从1开始)
}
return 0; // 未找到
}

算法分析:

  • 时间复杂度:O(n)
  • 返回值:找到返回位序(1~length),未找到返回0
  • 查找策略:顺序查找,返回第一个匹配元素

五、插入与删除操作

5.1 插入元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Status ListInsert(SqList &L, int i, int e)
{
if (i < 1 || i > L.length + 1)
return ERROR;
if (L.length >= L.listsize)
{
cout << "顺序表已满,无法插入!" << endl;
return ERROR;
}

// 将第i个位置及之后的元素后移
for (int j = L.length - 1; j >= i - 1; j--)
{
L.elem[j + 1] = L.elem[j];
}
L.elem[i - 1] = e;
L.length++;
return OK;
}

算法分析:

  • 时间复杂度:O(n)
  • 插入位置:可以在1到length+1之间(包括尾部插入)
  • 关键步骤:从后往前移动元素,避免数据覆盖

5.2 删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Status ListDelete(SqList &L, int i, int &e)
{
if (i < 1 || i > L.length)
return ERROR;

e = L.elem[i - 1];

// 将第i个位置之后的元素前移
for (int j = i; j < L.length; j++)
{
L.elem[j - 1] = L.elem[j];
}
L.length--;
return OK;
}

算法分析:

  • 时间复杂度:O(n)
  • 返回值:通过引用参数e返回被删除的元素
  • 关键步骤:从前往后移动元素

六、扩展功能实现

6.1 创建顺序表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void CreateList(SqList &L, int n)
{
if (n <= 0 || n > MAXSIZE)
{
cout << "输入的长度不合法!" << endl;
return;
}

cout << "请依次输入" << n << "个数据:" << endl;
for (int i = 0; i < n; i++)
{
cout << "第" << (i + 1) << "个数据: ";
cin >> L.elem[i];
}
L.length = n;
cout << "顺序表创建成功!" << endl;
}

6.2 打印顺序表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void PrintList(SqList L)
{
if (L.length == 0)
{
cout << "顺序表为空!" << endl;
return;
}

cout << "顺序表内容: ";
for (int i = 0; i < L.length; i++)
{
cout << L.elem[i] << " ";
}
cout << endl;
}

6.3 排序(冒泡排序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void SortList(SqList &L)
{
if (L.length <= 1)
return;

for (int i = 0; i < L.length - 1; i++)
{
for (int j = 0; j < L.length - 1 - i; j++)
{
if (L.elem[j] > L.elem[j + 1])
{
int temp = L.elem[j];
L.elem[j] = L.elem[j + 1];
L.elem[j + 1] = temp;
}
}
}
}

算法分析:

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)
  • 排序方式:升序排列

6.4 逆置顺序表

1
2
3
4
5
6
7
8
9
10
11
12
void ReverseList(SqList &L)
{
if (L.length <= 1)
return;

for (int i = 0; i < L.length / 2; i++)
{
int temp = L.elem[i];
L.elem[i] = L.elem[L.length - 1 - i];
L.elem[L.length - 1 - i] = temp;
}
}

算法分析:

  • 时间复杂度:O(n)
  • 方法:首尾对称交换

6.5 查找最大值和最小值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Status FindMax(SqList L, int &max)
{
if (L.length == 0)
return ERROR;

max = L.elem[0];
for (int i = 1; i < L.length; i++)
{
if (L.elem[i] > max)
max = L.elem[i];
}
return OK;
}

Status FindMin(SqList L, int &min)
{
if (L.length == 0)
return ERROR;

min = L.elem[0];
for (int i = 1; i < L.length; i++)
{
if (L.elem[i] < min)
min = L.elem[i];
}
return OK;
}

算法分析:

  • 时间复杂度:O(n)
  • 方法:遍历一次找出最值

6.6 合并两个有序顺序表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
SqList MergeList(SqList La, SqList Lb)
{
SqList Lc;
InitList(Lc);

int i = 0, j = 0, k = 0;

while (i < La.length && j < Lb.length)
{
if (La.elem[i] <= Lb.elem[j])
{
Lc.elem[k++] = La.elem[i++];
}
else
{
Lc.elem[k++] = Lb.elem[j++];
}
}

while (i < La.length)
{
Lc.elem[k++] = La.elem[i++];
}

while (j < Lb.length)
{
Lc.elem[k++] = Lb.elem[j++];
}

Lc.length = k;
return Lc;
}

算法分析:

  • 时间复杂度:O(m+n)
  • 前提条件:两个顺序表都已排序
  • 归并策略:双指针法

6.7 去除重复元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void RemoveDuplicate(SqList &L)
{
if (L.length <= 1)
return;

int newLength = 1;
for (int i = 1; i < L.length; i++)
{
bool isDuplicate = false;
for (int j = 0; j < newLength; j++)
{
if (L.elem[i] == L.elem[j])
{
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
L.elem[newLength++] = L.elem[i];
}
}
L.length = newLength;
}

算法分析:

  • 时间复杂度:O(n²)
  • 策略:保留第一次出现的元素
  • 优化建议:可以先排序再去重,时间复杂度降为O(nlogn)

七、交互式菜单系统

7.1 菜单显示

1
2
3
4
5
6
7
8
9
void ShowMenu()
{
cout << "\n========== 顺序表操作菜单 ==========" << endl;
cout << "1. 创建顺序表" << endl;
cout << "2. 插入元素" << endl;
// ... 其他菜单项
cout << "0. 退出程序" << endl;
cout << "====================================" << endl;
}

7.2 主函数框架

主函数实现了一个完整的交互式界面,通过switch语句处理用户的各种操作选择,提供了15种不同的功能操作。

八、总结

8.1 顺序表的优缺点

优点:

  • 随机访问,时间复杂度O(1)
  • 存储密度高,无需额外空间存储指针
  • 实现简单,易于理解

缺点:

  • 插入删除效率低,平均时间复杂度O(n)
  • 需要预先分配固定大小的空间
  • 空间利用率可能不高

8.2 时间复杂度总结

操作 时间复杂度
初始化 O(1)
销毁 O(1)
按位置访问 O(1)
按值查找 O(n)
插入 O(n)
删除 O(n)
排序 O(n²)
逆置 O(n)
合并 O(m+n)

8.3 实际应用场景

  1. 需要频繁随机访问的场景
  2. 数据规模相对固定
  3. 插入删除操作较少
  4. 例如:成绩管理、数组处理等

完整代码,可直接编译运行体验各项功能!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
#define MAXSIZE 100 // 最大容量
#define ERROR 0
#define OK 1
#define OVERFLOW (-1)
#include <iostream>
#include <cstdlib>
using namespace std;
typedef int Status;

// 顺序表结构定义
typedef struct
{
int *elem; // 存储空间基址
int length; // 当前长度
int listsize; // 当前分配的存储容量
} SqList;

// 初始化顺序表
Status InitList(SqList &L)
{
L.elem = new int[MAXSIZE];
if (!L.elem)
return OVERFLOW;
L.length = 0;
L.listsize = MAXSIZE;
cout << "顺序表初始化成功!" << endl;
return OK;
}

// 销毁顺序表
void DestroyList(SqList &L)
{
if (L.elem)
{
delete[] L.elem;
L.elem = NULL;
L.length = 0;
L.listsize = 0;
}
}

// 清空顺序表
void ClearList(SqList &L)
{
L.length = 0;
cout << "顺序表已清空!" << endl;
}

// 判断顺序表是否为空
bool ListEmpty(SqList L)
{
return L.length == 0;
}

// 获取顺序表长度
int ListLength(SqList L)
{
return L.length;
}

// 获取指定位置的元素
Status GetElem(SqList L, int i, int &e)
{
if (i < 1 || i > L.length)
return ERROR;
e = L.elem[i - 1];
return OK;
}

// 查找元素(返回第一个匹配的位置)
int LocateElem(SqList L, int e)
{
for (int i = 0; i < L.length; i++)
{
if (L.elem[i] == e)
return i + 1; // 返回位序(从1开始)
}
return 0; // 未找到
}

// 在指定位置插入元素
Status ListInsert(SqList &L, int i, int e)
{
if (i < 1 || i > L.length + 1)
return ERROR;
if (L.length >= L.listsize)
{
cout << "顺序表已满,无法插入!" << endl;
return ERROR;
}

// 将第i个位置及之后的元素后移
for (int j = L.length - 1; j >= i - 1; j--)
{
L.elem[j + 1] = L.elem[j];
}
L.elem[i - 1] = e;
L.length++;
return OK;
}

// 删除指定位置的元素
Status ListDelete(SqList &L, int i, int &e)
{
if (i < 1 || i > L.length)
return ERROR;

e = L.elem[i - 1];

// 将第i个位置之后的元素前移
for (int j = i; j < L.length; j++)
{
L.elem[j - 1] = L.elem[j];
}
L.length--;
return OK;
}

// 创建顺序表
void CreateList(SqList &L, int n)
{
if (n <= 0 || n > MAXSIZE)
{
cout << "输入的长度不合法!" << endl;
return;
}

cout << "请依次输入" << n << "个数据:" << endl;
for (int i = 0; i < n; i++)
{
cout << "第" << (i + 1) << "个数据: ";
cin >> L.elem[i];
}
L.length = n;
cout << "顺序表创建成功!" << endl;
}

// 打印顺序表
void PrintList(SqList L)
{
if (L.length == 0)
{
cout << "顺序表为空!" << endl;
return;
}

cout << "顺序表内容: ";
for (int i = 0; i < L.length; i++)
{
cout << L.elem[i] << " ";
}
cout << endl;
}

// 顺序表排序(冒泡排序)
void SortList(SqList &L)
{
if (L.length <= 1)
return;

for (int i = 0; i < L.length - 1; i++)
{
for (int j = 0; j < L.length - 1 - i; j++)
{
if (L.elem[j] > L.elem[j + 1])
{
int temp = L.elem[j];
L.elem[j] = L.elem[j + 1];
L.elem[j + 1] = temp;
}
}
}
}

// 逆置顺序表
void ReverseList(SqList &L)
{
if (L.length <= 1)
return;

for (int i = 0; i < L.length / 2; i++)
{
int temp = L.elem[i];
L.elem[i] = L.elem[L.length - 1 - i];
L.elem[L.length - 1 - i] = temp;
}
}

// 查找最大值
Status FindMax(SqList L, int &max)
{
if (L.length == 0)
return ERROR;

max = L.elem[0];
for (int i = 1; i < L.length; i++)
{
if (L.elem[i] > max)
max = L.elem[i];
}
return OK;
}

// 查找最小值
Status FindMin(SqList L, int &min)
{
if (L.length == 0)
return ERROR;

min = L.elem[0];
for (int i = 1; i < L.length; i++)
{
if (L.elem[i] < min)
min = L.elem[i];
}
return OK;
}

// 合并两个有序顺序表
SqList MergeList(SqList La, SqList Lb)
{
SqList Lc;
InitList(Lc);

int i = 0, j = 0, k = 0;

while (i < La.length && j < Lb.length)
{
if (La.elem[i] <= Lb.elem[j])
{
Lc.elem[k++] = La.elem[i++];
}
else
{
Lc.elem[k++] = Lb.elem[j++];
}
}

while (i < La.length)
{
Lc.elem[k++] = La.elem[i++];
}

while (j < Lb.length)
{
Lc.elem[k++] = Lb.elem[j++];
}

Lc.length = k;
return Lc;
}

// 去重(保留第一次出现的元素)
void RemoveDuplicate(SqList &L)
{
if (L.length <= 1)
return;

int newLength = 1;
for (int i = 1; i < L.length; i++)
{
bool isDuplicate = false;
for (int j = 0; j < newLength; j++)
{
if (L.elem[i] == L.elem[j])
{
isDuplicate = true;
break;
}
}
if (!isDuplicate)
{
L.elem[newLength++] = L.elem[i];
}
}
L.length = newLength;
}

// 显示菜单
void ShowMenu()
{
cout << "\n========== 顺序表操作菜单 ==========" << endl;
cout << "1. 创建顺序表" << endl;
cout << "2. 插入元素" << endl;
cout << "3. 删除元素" << endl;
cout << "4. 查找元素(按值)" << endl;
cout << "5. 获取元素(按位置)" << endl;
cout << "6. 获取顺序表长度" << endl;
cout << "7. 打印顺序表" << endl;
cout << "8. 排序顺序表" << endl;
cout << "9. 逆置顺序表" << endl;
cout << "10. 清空顺序表" << endl;
cout << "11. 判断顺序表是否为空" << endl;
cout << "12. 查找最大值" << endl;
cout << "13. 查找最小值" << endl;
cout << "14. 去除重复元素" << endl;
cout << "15. 合并两个有序顺序表" << endl;
cout << "0. 退出程序" << endl;
cout << "====================================" << endl;

}

int main()
{
SqList L;
InitList(L);

int choice, n, position, elem;
Status result;
ShowMenu();
while (true)
{
cout << "请选择操作: ";
cin >> choice;

switch (choice)
{
case 1: // 创建顺序表
cout << "请输入要创建的顺序表长度: ";
cin >> n;
CreateList(L, n);
break;

case 2: // 插入元素
cout << "请输入插入位置(1-" << (L.length + 1) << "): ";
cin >> position;
cout << "请输入插入的元素值: ";
cin >> elem;
result = ListInsert(L, position, elem);
if (result == OK)
cout << "插入成功!" << endl;
else
cout << "插入失败!位置不合法。" << endl;
break;

case 3: // 删除元素
cout << "请输入要删除的位置(1-" << L.length << "): ";
cin >> position;
result = ListDelete(L, position, elem);
if (result == OK)
cout << "删除成功!删除的元素为: " << elem << endl;
else
cout << "删除失败!位置不合法。" << endl;
break;

case 4: // 查找元素
cout << "请输入要查找的元素值: ";
cin >> elem;
position = LocateElem(L, elem);
if (position != 0)
cout << "元素 " << elem << " 在第 " << position << " 个位置" << endl;
else
cout << "未找到元素 " << elem << endl;
break;

case 5: // 获取元素
cout << "请输入要获取的位置(1-" << L.length << "): ";
cin >> position;
result = GetElem(L, position, elem);
if (result == OK)
cout << "第 " << position << " 个位置的元素为: " << elem << endl;
else
cout << "获取失败!位置不合法。" << endl;
break;

case 6: // 获取长度
cout << "顺序表长度为: " << ListLength(L) << endl;
break;

case 7: // 打印顺序表
PrintList(L);
break;

case 8: // 排序
if (ListEmpty(L))
{
cout << "顺序表为空,无法排序!" << endl;
}
else
{
SortList(L);
cout << "排序完成!" << endl;
PrintList(L);
}
break;

case 9: // 逆置
if (ListEmpty(L))
{
cout << "顺序表为空,无法逆置!" << endl;
}
else
{
ReverseList(L);
cout << "逆置完成!" << endl;
PrintList(L);
}
break;

case 10: // 清空顺序表
ClearList(L);
break;

case 11: // 判断是否为空
if (ListEmpty(L))
cout << "顺序表为空" << endl;
else
cout << "顺序表不为空,长度为: " << ListLength(L) << endl;
break;

case 12: // 查找最大值
result = FindMax(L, elem);
if (result == OK)
cout << "顺序表的最大值为: " << elem << endl;
else
cout << "顺序表为空!" << endl;
break;

case 13: // 查找最小值
result = FindMin(L, elem);
if (result == OK)
cout << "顺序表的最小值为: " << elem << endl;
else
cout << "顺序表为空!" << endl;
break;

case 14: // 去重
if (ListEmpty(L))
{
cout << "顺序表为空!" << endl;
}
else
{
RemoveDuplicate(L);
cout << "去重完成!" << endl;
PrintList(L);
}
break;

case 15: // 合并两个有序顺序表
{
SqList L2;
InitList(L2);
cout << "请输入第二个顺序表的长度: ";
cin >> n;
CreateList(L2, n);

cout << "对两个顺序表进行排序..." << endl;
SortList(L);
SortList(L2);

SqList L3 = MergeList(L, L2);
cout << "合并后的顺序表: ";
PrintList(L3);

DestroyList(L2);
DestroyList(L3);
break;
}

case 0: // 退出
DestroyList(L);
cout << "程序已退出,感谢使用!" << endl;
return 0;

default:
cout << "无效的选择,请重新输入!" << endl;
break;
}
}

return 0;
}

  • 标题: 顺序表(Sequential List)的完整实现与详解~
  • 作者: 星隐
  • 创建于 : 2025-10-24 17:40:04
  • 更新于 : 2026-01-19 01:58:27
  • 链接: https://www.starin.top/post/8cfd498ba3aa/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。