调整数组使奇数全部都位于偶数前面
✍写在正文前:这道题需要考虑到种种可能,因此特地写文章记录!
题目:输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。
🖥先说最基本的思路
- 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置
- 循环进行一下操作
a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环
b. left从前往后找,找到一个偶数后停止
c. right从后往前找,找到一个奇数后停止
d. 如果left和right都找到了对应的数据,则交换,继续a,
代码雏形:
#define _CRT_SECURE_NO_WARNINGS
#include <Stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int *left = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int *right = &arr[sz-1];
while (left < right)
{
while(*left % 2 == 1)//从左向右找一个偶数
{
left++;
}
while (*right % 2 == 0)//从右向左找一个奇数
{
right--;
}
int tmp = *right;
*right = *left;
*left = tmp;
}
for (int i = 0; i < sz - 1; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
拿着键盘咔咔咔一顿写,那看看答案?
一眼看过去,好像是排列好了,🧨但是!6为什么会在5前面?!
仔细分析:
解决方法:
在left和right交换前,增加一个if(*left<*right)用以判断
if (left < right)
{
int tmp = *right;
*right = *left;
*left = tmp;
}
此时效果:
🧐那么到这里真的完成了么?我们还需要考虑一种特殊情况
如果都为奇数or都为偶数时,这里假设都为奇数,则left指针一直向后移,最后越界
针对这个问题,在每次left去遍历偶数时,增加一个限制条件:
while((left<right)&&(left%2==1))
最终代码:
#include <Stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
int *left = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
int *right = &arr[sz-1];
for (int i = 0; i < sz - 1; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
while (left < right)
{
while((left < right)&&*left % 2 == 1)//从左向右找一个偶数
{
left++;
}
while ((left < right) && *right % 2 == 0)//从右向左找一个奇数
{
right--;
}
if (left < right)
{
int tmp = *right;
*right = *left;
*left = tmp;
}
}
for (int i = 0; i < sz - 1; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
💿总结:所以当你以一个常例去写完一个代码时候,看似没问题,实际上还要多去考虑特殊情况避免出现错误
; i < sz - 1; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
💿总结:所以当你以一个常例去写完一个代码时候,看似没问题,实际上还要多去考虑特殊情况避免出现错误