如何修改以下C语言简单排序算法使其仅在单个数组arr[]上执行操作?
实现原地选择排序(移除额外数组)
嘿,我来帮你把这个排序改成完全原地操作,再也不需要额外的res数组啦!先拆解下原代码的逻辑:你每次找出数组里的最大值,把原位置设为0(标记已处理),再把最大值放到res的对应位置。其实我们可以直接在原数组上调整元素位置,彻底摆脱额外空间的依赖。
修改后的完整代码
#include <stdio.h> void main(){ int arr [] = {1, 14, 5, 18, 3, 1}; int n = sizeof(arr)/sizeof(arr[0]); // 自动计算数组长度,不用硬编码6 // 外层循环:从数组末尾开始,逐步扩大已排序区域 for(int i = n - 1; i >= 0; i--) { int max_val = arr[0]; int max_index = 0; // 遍历未排序区域(0到i),找到最大值的位置 for(int k = 1; k <= i; k++){ if(arr[k] > max_val){ max_val = arr[k]; max_index = k; } } // 把最大值交换到当前未排序区域的最后位置(也就是它的最终排序位置) int temp = arr[i]; arr[i] = max_val; arr[max_index] = temp; } // 直接打印原数组,已经是排序好的结果 for (int z = 0; z < n; z++){ printf("%d ", arr[z]); } }
关键改动说明
- 移除额外数组:直接删掉了
res数组,所有排序逻辑都在原arr上执行 - 替换标记逻辑:原代码用
arr[y] = 0标记已处理元素,存在bug(如果数组本身包含0,会被误判为已处理)。现在改用交换位置的方式,把最大值放到它的最终固定位置,后续循环只处理前面的未排序区域(外层循环i递减,未排序范围逐步缩小) - 更通用的长度计算:用
sizeof(arr)/sizeof(arr[0])自动获取数组长度,不用写死6,适配不同长度的数组 - 逻辑更严谨:每次交换后,当前
i位置的元素就固定为已排序状态,不会再被后续循环修改,逐步完成整个数组的排序
运行这段代码,你会得到和原代码完全一致的输出:1 1 3 5 14 18,但全程只用到了原数组哦!
内容的提问来源于stack exchange,提问作者Wojciech Mierzejewski
相关产品推荐
相关产品推荐

