首先,思路最重要
1,可以想到,就好像调座位;我们是不是可以通过检验坐在第一排的同学是不是男同学,以及坐在最后一的元素是不是女同学;
如果坐在第一排的是男,坐在最后一排是女,我们就将他们两交换位置,让女同学坐在第一排
如果第一排是男同学,最后一排也是男同学,那么我们就让最后一排减一,看他前面的是不是女同学
是就换,不是就不换;第一排也是依此类推
先写出框架;具体进行完善:
void print(int arr[], int sz) {//打印数组
int i = 0;
for (i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
}
void subs(int arr[], int sz) {//交换
}
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
subs(arr, sz);//置换奇数与偶数
print(arr, sz);//打印数组
return 0;
}
我们要考虑到第一个元素是不是奇数,不是就和后面的换成奇数;是就不换,令它++;看它后面的是不是,是就停止移动,不是继续移动;
void subs(int arr[], int sz) {
int left = 0;
int right = sz - 1;
while (arr[left] % 2!= 0) {//条件成立,则left下标元素是奇数,不用置换
left++;
}
}
然后还要考虑最后的元素是不是奇数;不是就看后面元素的前一位
void subs(int arr[], int sz) {
int left = 0;
int right = sz - 1;
while (left < right && arr[left] % 2!= 0) {//条件成立,则left下标元素是奇数,不用置换
left++;
}
while (left < right && arr[right] % 2 == 0) {//条件成立,则right下标元素是偶数,不用置换
right--;//看他前面的
}
}
经过查找,符合后开始置换
void subs(int arr[], int sz) {
int left = 0;
int right = sz - 1;
while (left < right && arr[left] % 2!= 0) {//条件成立,则left下标元素是奇数,不用置换
left++;
}
while (left < right && arr[right] % 2 == 0) {//条件成立,则right下标元素是偶数,不用置换
right--;
}
if (left < right) {//置换
int a = arr[left];
arr[left] = arr[right];
arr[right] = a;
}
}
程序一走,结果没问题;
但是真就完了吗?
程序是严谨的,当数组元素都是偶数或者奇数时呢?答案是:会发生越界访问!
给定一个都是奇数的数组:
调试:当left==right时、此时访问到的right的元素
如果继续调试呢?程序并没有停止;没有条件限制,它开始越界访问;
此时程序访问到了数组外;这个是一个随机值
于是为了防止程序的越界访问,我们应该优化它;减少它存在Bug的可能性;
于是:
void subs(int arr[], int sz) {
int left = 0;
int right = sz - 1;
while (left < right) {
while (left < right && arr[left] % 2!= 0) {//条件成立,则left下标元素是奇数,不用置换
left++;//left<right防止数组全是奇数时,向后越界访问
}
while (left < right && arr[right] % 2 == 0) {//条件成立,则right下标元素是偶数,不用置换
right--;//left<right防止数组全是偶数时,向前越界访问
}
if (left < right) {
int a = arr[left];
arr[left] = arr[right];
arr[right] = a;
}
}
}
最后完整的代码如下:
#include<stdio.h>
void print(int arr[], int sz) {//打印数组
int i = 0;
for (i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
}
void subs(int arr[], int sz) {
int left = 0;//首下标
int right = sz - 1;尾下标
while (left < right) {
while (left < right && arr[left] % 2!= 0) {//条件成立,则left下标元素是奇数,不用置换
left++;
}
while (left < right && arr[right] % 2 == 0) {//条件成立,则right下标元素是偶数,不用置换
right--;//while条件left<right是为了防止数组全是偶数或奇数时,导致++越界访问
}
if (left < right) {//置换
int a = arr[left];
arr[left] = arr[right];
arr[right] = a;
}
}
}
int main() {
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int sz = sizeof(arr) / sizeof(arr[0]);
subs(arr, sz);//置换奇数与偶数
print(arr, sz);//打印数组
return 0;
}