C语言——小知识和小细节13

文章介绍了两种方法将数组中的奇数放在偶数前面:一种是冒泡排序变种,效率较低可能需要多次遍历;另一种是利用两个箭头遍历,效率更高只需一次遍历。同时讲解了如何合并两个升序序列成一个有序序列。
摘要由CSDN通过智能技术生成

1、将数组中的奇数放到数组前部分,将偶数放后部分

一个有若干奇数和若干偶数的数组,例如

	int arr[10] = { 2,4,6,8,10,7,1,3,3,9 };

将奇数放到数组前部分,将偶数放后部分,就像这样:

	int arr[10] = { 7,1,3,3,9,2,4,6,8,10 };

方法一:用冒泡排序变种

#include <stdio.h>

int main()
{
	int arr[10] = { 2,4,6,8,10,7,1,3,3,9 };
	int i = 0, j = 0,temp = 0;
	for (i = 0; i < 9; i++)
	{
		for (j = 0; j < 9 - i; j++)
		{
			if (arr[j] % 2 == 0 && arr[j + 1] % 2 == 1)
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

类似冒泡排序,只要偶数在奇数前面,就交换,最坏的情况是:

	int arr[10] = { 2,4,6,8,10,2,4,4,2,5 };

在数组最尾部有一个奇数,其他的都是偶数,最坏的情况需要9轮。

运行结果:

方法二:用两个箭头遍历数组

#include <stdio.h>

void odd_even(int arr[],int len)
{
	int left = 0, right = len - 1,temp = 0;
	while (left < right)
	{
		while ((left < len - 1) && arr[left] % 2 == 1)// 这里的前半部分条件是为了防止当数组全是奇数导致越界访问
		{
			left++;// left作为在左面的的箭头,通过这个循环找偶数,只要是奇数循环则会继续,只要是偶数循环则会停下,left这个箭头就会指向偶数
		}
		while ((right > 0) && arr[right] % 2 == 0)// 这里的前半部分条件是为了防止当数组全是偶数导致越界访问
		{
			right--;// right作为在左面的的箭头,通过这个循环找奇数,只要是偶数循环则会继续,只要是奇数循环则会停下,right这个箭头就会指向偶数
		}
		if (left < right)// 这时将left指向的元素和right指向的元素交换
		{
			temp = arr[left];
			arr[left] = arr[right];
			arr[right] = temp;
			left++;
			right--;
		}
	}
}

int main()
{
	int arr[10] = { 2,4,6,8,10,1,3,5,7,9 };
	int i = 0;
	int len = sizeof(arr) / sizeof(int);

	odd_even(arr, len);

	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

这种方法效率更高,只用遍历一次数组就可以实现目的。

2、有序序列合并

输入两个升序序列,将这两个序列合并成一个有序序列并输出。

#include <stdio.h>

int main()
{
	int m = 0, n = 0,i = 0,j = 0;
	scanf("%d %d", &m, &n);// 分别表示第一个和第二个数组的元素个数
	int arr1[100];
	int arr2[100];
	for (i = 0; i < m; i++)// 输入第一个序列
	{
		scanf("%d", &arr1[i]);
	}
	for (i = 0; i < n; i++)// 输入第二个序列
	{
		scanf("%d", &arr2[i]);
	}
	i = 0;// 将i置零
	while (i < m && j < n)// 只要有一个序列打印完了,循环就结束
	{
		if (arr1[i] < arr2[j])// i和j分别遍历两个序列,只要i指向的元素小于j指向的元素,就打印i指向的元素,然后i++,否则打印j指向的元素,然后j++
		{
			printf("%d ", arr1[i]);
			i++;
		}
		else
		{
			printf("%d ", arr2[j]);
			j++;
		}
	}
	if (i < m)// 只要其中一个序列先打印完,就会剩余一些元素,打印剩余的部分
	{
		for (; i < m; i++)
		{
			printf("%d ", arr1[i]);
		}
	}
	else
	{
		for (; j < n; j++)
		{
			printf("%d ", arr2[j]);
		}
	}
	return 0;
}

运行结果:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值