算法1-3~4 将数组中元素反转存放
分数 15
作者 陈越
单位 浙江大学
给定 n 个 int 型范围内的整数。请编写程序,将 n 个整数存在数组中,再将这些数组元素反转存放,最后顺序输出反转后数组中的元素。
注:虽然不需要改变数组中元素的位置,也可以按反转的顺序输出,但建议练习者尝试反转数组元素的算法。
输入格式:
输入第一行给出正整数 n(≤104)。第二行给出 n 个 int 型范围内的整数。同行数字间以空格分隔。
输出格式:
在一行中输出反转输入顺序后的结果,每个数字后跟 1 个空格。
输入样例:
输出样例:
答案1(静态数组)
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
| #include<iostream> using namespace std;
void reverseArray(int *a, int length) { int j = length - 1; for (int i = 0; i < j; i++, j--) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } }
int main() { int n; cin >> n; int a[1000]; for (int i = 0; i < n; i++) { cin >> a[i]; } reverseArray(a, n); for (int i = 0; i < n; i++) { cout << a[i] << " "; } }
|
改进:
- 使用动态内存分配可以更灵活地管理内存,避免固定大小数组可能带来的空间浪费或溢出风险。结合顺序表(
sqList)的思想
- 顺序表结构:使用
SqList结构体封装了数据指针和长度,更符合数据结构的规范,也方便扩展其他操作(如插入、删除等)。
- 动态内存分配:
- 根据输入的
n动态分配刚好足够的内存空间,避免固定数组的空间浪费
答案2(顺序表)
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
| #include<iostream> using namespace std;
typedef struct { int *elem; int length; } sqList;
void InitList(sqList &L, int n) { L.elem = new int[n]; L.length = 0; }
void reverseList(sqList &L) { int j = L.length - 1; for (int i = 0; i < j; i++, j--) { int t = L.elem[i]; L.elem[i] = L.elem[j]; L.elem[j] = t; } }
void destroyList(sqList &L) { if (L.elem != nullptr) { delete[] L.elem; L.elem = nullptr; L.length = 0; } }
int main() { int n; cin >> n; sqList L; InitList(L, n); for (int i = 0; i < n; i++) { cin >> L.elem[i]; L.length++; } reverseList(L); for (int i = 0; i < L.length; i++) { cout << L.elem[i] << " "; }
destroyList(L); }
|
- 注意:
- 初始化顺序表的时候要为数组开辟一块空间
L.elem = new int[n];
- 要把当前表长置为空
L.length = 0;
为什么 destroyList 需要引用传递?
destroyList 的核心功能是:
- 释放
L.data 指向的动态内存
- 将
L.data 置为 nullptr(避免野指针)
- 将
L.length 重置为 0
这些操作都需要修改原始顺序表 L 的成员变量。如果不用引用(即写成 destroyList(SqList L)):
- 函数会接收
L 的副本(值传递)
- 释放的是副本中
data 指向的内存(虽然也能释放动态内存,避免泄漏)
- 但原始
L 的 data 仍会指向已释放的内存(变成野指针),length 也不会被重置
这会导致原始顺序表处于无效状态,存在风险。