一维数组按首元素分区排序函数失效?求排查与修正方案
问题分析与修正方案
首先明确你的需求:基于数组首元素做分区,将所有小于首元素的元素移到它前面,大于等于的移到它后面。咱们先来看看原代码里存在的几个关键问题:
原代码的核心问题
- 无意义的重复调用:在
main函数里你写了for (i = 0; i < m; i++) sort(a, m);,这会把分区函数执行m次,完全没必要——分区操作只需要跑一次就够了。 - 基准元素选错:
sort函数里你把p = a[1]当成了分区基准,但题目要求的是用**数组首元素(a[0])**来做判断依据。 - 分区逻辑失效:当前
sort的逻辑只是简单交换a[j]和a[1],并没有真正把所有小于基准的元素归集到前面,根本完不成完整的分区任务。
修正后的完整实现
我们可以用单指针的方式实现高效分区:遍历数组时把小于首元素的元素逐步交换到前面的预留位置,最后把首元素放到正确的分界点上。
#include<stdio.h> void partition(int a[], int n); int main(){ int a[10], i, m; do{ printf("Enter number of elements: "); scanf("%d", &m); } while (m < 1 || m > 10); for (i = 0; i < m; i++) scanf("%d", &a[i]); // 仅需调用一次分区函数 partition(a, m); for (i = 0; i < m; i++) printf("%d ", a[i]); return 0; } void partition(int a[], int n){ if (n <= 1) return; // 数组长度≤1时无需分区,直接返回 int pivot = a[0]; // 以首元素作为分区基准 int pos = 1; // 标记下一个小于基准的元素应该放置的位置 for (int i = 1; i < n; i++){ if (a[i] < pivot){ // 交换当前元素到pos位置,pos后移一位 int temp = a[i]; a[i] = a[pos]; a[pos] = temp; pos++; } } // 最后把基准元素放到正确的分界点(pos-1的位置) a[0] = a[pos-1]; a[pos-1] = pivot; }
代码逻辑说明
- 基准明确:严格使用数组首元素
a[0]作为分区判断的基准。 - 单指针高效遍历:用
pos变量记录下一个可放置“小于基准元素”的位置,遍历过程中遇到符合条件的元素就交换到pos处,然后pos自增。 - 基准归位:遍历结束后,把基准元素交换到
pos-1的位置,此时左边全是小于基准的元素,右边全是大于等于基准的元素。 - 边界处理:增加了数组长度≤1时直接返回的逻辑,避免无意义的运算。
举个测试例子:输入数组[5,3,8,2,7,1],分区后会得到[3,2,1,5,8,7],完全符合你的需求。
内容的提问来源于stack exchange,提问作者pollux552
相关产品推荐
相关产品推荐

