C语言——双指针问题

问题一:

要求编写程序,将顺序读入的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 <stdio.h>
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 <stdio.h>
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;
} 

运行结果:

 

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值