C语言编程:奇偶分治排序最后一轮无变化问题排查
排查数组奇偶分区的逻辑bug
嘿,我来帮你揪出这个问题!听起来你在做那个经典的「数组左奇右偶」分区练习,要求O(N)时间复杂度对吧?你提到最后比较4和-3时本该进入第一个if分支却没执行,这个问题大概率出在负数的奇偶判断逻辑上,咱们一步步拆解:
最可能的原因:负数取模的判断失误
很多编程语言里,负数取模的结果符号会和被除数保持一致。比如在C++/Java里,-3 % 2的结果是-1,而不是你直觉里的1。如果你的代码里判断奇数的条件是num % 2 == 1,那-3就不会被识别为奇数——这就直接导致当右指针指向-3时,你的代码误以为它是偶数,自然不会触发交换的if分支。
修正方案:
把奇数判断改成以下两种方式之一,就能兼容正负整数:
- 检查
num % 2 != 0(只要除以2有余数就是奇数) - 先取绝对值再判断:
abs(num) % 2 == 1
其他可能的排查方向
如果奇偶判断没问题,再看看这两个点:
- 指针移动逻辑:你的双指针(左找偶数、右找奇数)的循环条件是不是
left < right?有没有在找到目标元素后忘记移动指针?比如左指针停在4(偶数),右指针停在-3(奇数),但如果循环条件已经不满足(比如left >= right),那也不会进入交换分支。 - 数组边界处理:右指针的初始值是不是
n-1?如果误写成n,会导致越界或者访问到错误的元素,影响最后一次判断。
参考的正确双指针实现示例
给你一个标准的O(N)时间复杂度的实现框架,你可以对照自己的代码找差异:
void partitionOddEven(int arr[], int n) { int left = 0; int right = n - 1; while (left < right) { // 左指针向右找第一个偶数 while (left < right && arr[left] % 2 != 0) { left++; } // 右指针向左找第一个奇数 while (left < right && arr[right] % 2 == 0) { right--; } // 交换两个元素,继续移动指针 if (left < right) { int temp = arr[left]; arr[left] = arr[right]; arr[right] = temp; left++; right--; } } }
你可以先重点检查奇偶判断的条件,这是这类问题里最容易踩的坑!
内容的提问来源于stack exchange,提问作者idan bar
相关产品推荐
相关产品推荐

