要求编写程序,将顺序读入的n个非负整数存入数组中,然后编写一个函数,调整该数组中元素顺序,使所有偶数元素之后跟着所有奇数元素。
你可以打印满足此条件的任意数组作为答案。(注意需要在原数组上操作,不能开辟一个新的空间来存数组)
输入格式:第一行输入 n 代表元素个数,然后依次输入 n个非负整数。
输入样例:
4
3 1 2 4
输出样例:
2 4 3 1(或 4 2 3 1或 2 4 1 3或 4 2 1 3中的任意一种)
此题要求所有偶数后面都跟着奇数,所以我们可以很顺利的想到,可以采用两个指针,
我们暂且分别命名为p,q两指针,进入循环,p指针从数组的第一个元素开始管偶数,q指
针从数组的最后一个元素开始管奇数,两指针对撞走,进行遍历。
接下来,我们可以思考一下,对于p,q指针的具体操作思路和循环退出的条件是怎么样
的呢?
情况1:考虑最特殊的情况,如果前面p所指的是奇数,q前面所指的是偶数,那很简单,
引入中间变量,直接把这两指针左右进行交换(这也是为什么我们可以想到用两个
指针,因为要进行交换);
情况2:如果p指针控制的偶数区域遍历到之后发现是偶数,那可以直接让p指针往右走;
情况3:如果q指针控制的奇数区域遍历到之后发现就是奇数,那就直接让q往左走。
最后:直到p,q指针相撞,则退出循环,打印数组。
#include
int main()
{
int n,i,temp;
int *p = NULL,*q = NULL;
scanf("%d",&n);
int arr[n];
for(i = 0;i < n;i++)
{
scanf("%d",&arr[i]);
}
//p,q赋值 分别从首尾开始
p = arr; //&arr[0]
q = arr + n - 1; //&arr[n - 1]
while(p < q) //进入循环条件是两个指针没相撞
{
if(*p % 2 != 0 && *q % 2 == 0) //前奇后偶,直接交换
{
temp = *p;
*p = *q;
*q = temp;
}
else if(*p % 2 == 0) //如果前面是偶,则继续往下遍历
{
p++;
}
else // if(q % 2 != 0)在这里也可以,就是如果后面是奇数,那q就往前遍历
{
q--;
}
}
for(i = 0;i < n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
要求编写程序,将顺序读入的n个非负整数存入数组中,然后编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
输入样例:
5
0 1 0 3 12
输出样例:
1 3 12 0 0
注意:必须在原数组上操作,不能拷贝额外的数组。(最好在一次遍历中完成)
思路:
这一题我们之所以考虑到用双指针,是因为我们可以把题目的意思简化成为,我最后要的
数组形式为前面是非0数,后面是0,所以我们来定义两个指针p,q,p指针起始赋值数组第
一个元素,管前面非0数,q指针起始赋值数组最后一个元素,管后面的0。
以上初始工作做完我们来一下具体操作:
首先,进入循环,条件依旧是p,q指针未相遇,让他们对撞着走;
如果p指针指向0,那就引入 一个新指针new,从p开始遍历到q结束,然后控制0的位置,
向后移动,移动之后要记得把q的值赋为0,然后让q继续往前一个,这样就可以保证每次0
都到了后面;
如果p指针的值不是0,那就让p继续往下遍历,每一次是0再进入上述是0的操作。
最后,当p,q指针相撞,退出循环。
#include
int main()
{
int *p = NULL,*q = NULL,*s;
int n,i;
scanf("%d",&n);
int arr[n];
for(i = 0;i < n;i++)
{
scanf("%d",&arr[i]);
}
p = arr; //p指针从第一个元素开始
q = arr + n - 1; //q指针从最后一个元素开始
while(p < q)
{
if(*p == 0)
{
for(s = p;s < q;s++) //等于0的情况,就往后放
{
*s = *(s+1);
}
*q = 0; //保证每次的最后一个数都是0
q--;
}
else
{
p++; //没遇到0就往后遍历
}
}
for(i = 0;i < n;i++)
{
printf("%d ",arr[i]);
}
return 0;
}