数组负数左移正数右移:两种C++实现方案优劣对比咨询
数组负数左移、正数右移:两种实现的优劣分析
我正在学习线上C++视频教程,针对“将数组中负数移至左侧、正数移至右侧”的问题,自行编写了实现代码,之后看到讲师的实现方案。两者运行结果一致,但我无法判断哪种代码更优,希望得到专业分析。
通用代码部分
#include <iostream> using namespace std; // Array construction struct Array { int A[10]; int size; int length; }; void Swap(int *des, int *source) { int temp = *des; *des = *source; *source = temp; }
讲师的实现代码
void Rearrange(Array* arr) { int i = 0; int j = arr->length - 1; while (i < j) { while (arr->A[i] < 0) i++; while (arr->A[i] >= 0) j--; if (i < j) Swap(&arr->A[i], &arr->A[j]); } }
我的实现代码
void ArrangeNegativeOnLeft(Array *arr) { int i = 0; int j = arr->length - 1; while (i < j) { if (arr->A[i] < 0) i++; if (arr->A[j] >= 0) j--; if (i < j) { Swap(&arr->A[i], &arr->A[j]); } } }
主函数代码
int main(){ Array r = { {2,-15, 3,-10,5,6,-44, 55}, 10, 8 }; //Rearrange(&r); ArrangeNegativeOnLeft(&r); // Display cout << "\n Elements are:\n"; for (int i = 0; i < r.length; i++) cout << r.A[i] << " "; cout << endl; }
(注:原主函数中arr应为r,已修正)
两种实现的优劣分析
1. 讲师代码的致命bug
首先要指出:讲师的代码存在逻辑错误——第二个while循环的条件写成了arr->A[i] >= 0,这完全不符合逻辑,正确的条件应该是arr->A[j] >= 0。按照原代码运行,当i找到第一个非负数后,j会持续左移直到i >= j(因为判断的是固定位置i的元素是否非负,而非j位置的元素),根本无法完成交换操作。只有修正这个笔误后,讲师的代码才能正常工作。
2. 修正后两者的效率对比
假设讲师代码修正了上述bug,我们来对比效率:
- 讲师的实现:内层使用
while循环一次性将i跳到第一个需要交换的非负位置,j跳到第一个需要交换的负位置,再执行交换。这种方式能减少循环迭代次数——比如左侧连续多个负数时,i直接跳到目标位置,无需逐次判断;右侧连续多个正数时同理。时间复杂度为O(n),但实际迭代次数更少,效率更高。 - 你的实现:每次循环最多只移动
i或j一步,或执行交换。比如左侧连续k个负数,需要循环k次才能将i移到目标位置,迭代次数更多。时间复杂度同样是O(n),但常数系数更大,效率稍低。
3. 可读性与健壮性
- 你的代码:逻辑直观清晰,每一步操作明确,不容易出现笔误,初学者更容易理解和维护,健壮性更强。
- 讲师的代码(修正后):效率更高,但写法紧凑,对逻辑严谨性要求更高,容易出现类似原代码中的笔误,可读性稍差。
4. 边界情况处理
两者在全负数、全正数、单个元素等边界场景下:
- 你的代码能正确处理所有情况;
- 讲师代码修正后也能正确处理,但原代码因bug会直接失败。
总结:如果讲师代码修正了笔误,其效率更优;你的代码逻辑更清晰、不易出错,适合学习和维护。实际开发中,优先保证逻辑正确,再根据场景优化效率。
内容的提问来源于stack exchange,提问作者F T
相关产品推荐
相关产品推荐

