算法1
1.创建一个新数组
2.将原数组遍历一遍把奇数复制下来(for循环1)
3.将原数组遍历一遍把偶数复制下来(for循环2)
4.将新数组的数据复制回到原数组(for循环3)
这个算法的时间复杂度为O(n),因为三个for循环都是并列的,3n即n。
空间复杂度也为O(n),因为创建了一个额外的与原数组等长的新数组。但这个空间复杂度有些过大。下面的空间复杂度为O(1)但存在bug
void Move(int arr[], int len)//定义一个移动数据的函数,再定义数组名和数组长度用来传参
{
int brr[100];//不知道数组具体大小,[ ]内写具体数字可能存在越界的风险,后面可使用动态内存
int j = 0;//brr下标
for (int i = 0; i < len; i++)//把奇数复制到brr里
{
if (arr[i] % 2 != 0)//是奇数
{
brr[j++] = arr[i];//brr[]里面不能用i,因为转移的数据在arr和brr里的下标并不匹配
}
}
for (int i = 0; i < len; i++)//把偶数复制到brr里
{
if (arr[i] % 2 == 0)//是偶数
{
brr[j++] = arr[i];//j的值会每次自己往后走
}
}
for (int i = 0; i < len; i++) {
arr[i] = brr[i];//将brr[i]复制给arr[i]
}
}
void Show(const int* arr, int len)//定义一个打印输出的函数Show,const后面的数据不能修改
{
for (int i = 0; i < len; i++)
printf("%4d", arr[i]);
printf("\n");
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13 };
Move(arr, sizeof(arr) / sizeof(arr[0]));//数组,长度操作
Show(arr, sizeof(arr) / sizeof(arr[0]));//打印
return 0;
}
算法2
类似于快速排序里面的一次划分。定义下标i从前往后遍历数组寻找偶数,定义下标j从后往前遍历数组寻找奇数,每找到一组奇数和偶数就将两个数互换位置,然后接着遍历,直到两个下标相遇错过后结束。这个是在原数组里进行操作,所以空间复杂度为O(1)。时间复杂度仍为O(n)。
void Move(int arr[], int len)
{
int i = 0;//起始下标
int j = len - 1;//结尾下标
int tmp;//交换数据的临时变量
while (i < j)//如果i>=j,就已经交换完了
{
while (i < j && arr[i] % 2 != 0)//在前面找偶数
i++;//不加i<j会越界
while (i < j && arr[j] % 2 == 0)//在后面找奇数,找奇数下标为j
j--;
//交换数据
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
void Show(const int* arr, int len)//定义一个打印输出的函数Show,const后面的数据不能修改
{
for (int i = 0; i < len; i++)
printf("%4d", arr[i]);
printf("\n");
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13 };
Move(arr, sizeof(arr) / sizeof(arr[0]));//数组,长度操作
Show(arr, sizeof(arr) / sizeof(arr[0]));//打印
return 0;
}