初识C语言 —— 数组(二)

软件设计有两种方式:一种方式是,使软件过于简单,明显没有缺陷;另一种方式是,使软件过于复杂,没有明显的缺陷。           ——C.A.R. Hoare

一、数组的排序算法

在上一篇博客中我们初步介绍了数组的理论知识。我们知道,数组是一组有序数据的集合,但这里的有序并不是按照数组元素的数值大小来排列的,而是指数组元素在数组中所处的位置。那如何才能将数组元素按照数值的大小进行排列呢?我们可以通过一些排序算法来实现,接下来我们会对一些常用的算法进行分析讲解,希望对大家有所启发。

1.选择法排序

选择排序算法指的是每次选择所要排序的数组中的最大值的数组元素,将这个个元素与最前面没有进行数组排序的数组元素的值互换。

可以说起来或许有点抽象,我们来看一个例子:

#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;
	int arr[10];
	int Tmp = 0;
	int ret = 0;
	printf("请输入值为数组赋值: \n");
	for (i = 0; i < 10; i++)
	{
		printf("a[%d] = ", i);
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < 9; i++)
	{
		Tmp = arr[i];
		ret = i;
		for (j = i + 1; j < 10; j++)
		{
			if (arr[j] < Tmp)
			{
				Tmp = arr[j];
				ret = j;
			}
		}
		arr[ret] = arr[i];
		arr[i] = Tmp;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述

在这个例子里面,我们我们声明一个整型数组用于存储我们输入的数字,而声明的两个整型变量则用于存储数最小的数组元素和记录该元素的位置,然后通过了我们前面讲过的循环嵌套进行了选择法排序,最终将排序好的数组进行输出,得到了正确的结果。

2.冒泡法排序

冒泡法排序排序指的是在进行排序的时候,每次比较数组中相邻的两个数组元素的值,将较小数数字(从小到大)排在较大的数字前面。

这里我们用冒泡排序完成上面那一道题目的要求:

#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;
	int arr[10];
	int Tmp = 0;
	printf("请输入值为数组赋值: \n");
	for (i = 0; i < 10; i++)
	{
		printf("arr[%d] = ", i);
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < 10; i++)
	{
		for (j = 9; j >= i; j--)
		{
			if (arr[j] < arr[j - 1])
			{
				Tmp = arr[j - 1];
				arr[j - 1] = arr[j];
				arr[j] = Tmp;
			}
		}
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述
对于此代码在这里就不进行详细解剖,其实大家会发现和选择排序法有同有异,可以进行一下对比分析,自己能把代码理解了才能更好的掌握,而不是一味的按图索骥。

3.交换法排序

交换法排序是将每一个数字与其后的所有数一一作比较,如果发现符合条件的数据,就进行交换数据。首先,我们用第一个数字一次与其后的所有数进行比较,如果存在比其值大(小)的数,则交换这两个数,继续向后比较,第二个数字也是如此,如此往复,以此类推就能完成。

同样的题目:

#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;
	int arr[10];
	int Tmp = 0;
	printf("请输入值为数组赋值: \n");
	for (i = 0; i < 10; i++)
	{
		printf("arr[%d] = ", i);
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < 9; i++)
	{
		for (j = i + 1; j < 10; j++)
		{
			if (arr[j] < arr[i])
			{
				Tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = Tmp;
			}
		}
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:
在这里插入图片描述
同样的,这种方法和上面两个方法的差别就在于第一个for循环以及内部的嵌套循环,大家可以自己先试着码一码,如果报错在寻找一下问题,毕竟讲一百次不如动手一次。

4.插入法排序

插入法排序较于前三种方法更为复杂,基本原理就是抽出一个数据,在前面的数据中寻找相应的位置插入,然后继续下一个数据,直到完成排序。

还是数组从小到大排序的题目:

#include <stdio.h>

int main()
{
	int i = 0;
	int j = 0;
	int arr[10];
	int Tmp = 0;
	int ret = 0;
	printf("请输入值为数组赋值: \n");
	for (i = 0; i < 10; i++)
	{
		printf("arr[%d] = ", i);
		scanf("%d", &arr[i]);
	}
	for (i = 0; i < 10; i++)
	{
		Tmp = arr[i];
		ret = i - 1;
		while ((ret >= 0) && (Tmp < arr[ret]))
		{
			arr[ret + 1] = arr[ret];
			ret--;
		}
		arr[ret + 1] = Tmp;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

在这里插入图片描述
在这个例子里面,我们用两个整型变量分别作为两个元素交换时的中间变量和记录数组元素位置,然后通过双重循环进行交换法排序,最后将数组输入,整个过程较为复杂,希望大家能多加理解。

排序算法的比较

前面我们介绍了四种算法,其实还有一种折半算法,但由于涉及到递归的知识,等我们后期再进行补充。现在我们就这4种算法进行简单的比较分析。

①.选择法排序

选择排序法排序较为简单,易于实现,适用于数量较小的排序,数量过大则需要谨慎使用。

②.冒泡法排序

冒泡法排序相对来说是更为稳定的排序方法,当等待排序的序列有序时,效果比较好。

③.交换法排序

交换法和冒泡法排序其实有很大相似,正序快逆序慢,排序有序数据时效果达到最好。

④.插入法排序

如果数据恰好应该插入序列的最后端,则不需要移动数据,可以节约运算时间,所以当原始数据基本有序时,插入法是具有较快的运算速度的。

二、字符串处理函数

在我们使用C语言编写程序的时候,我们经常要对字符或者字符串进行操作,有些操作我们可以通过字符函数和字符串函数来解决。C语言的标准库函数专门提供了一系列函数给我们,大大提高了我们的编程效率,下面我们会对一些常用的字符串处理函数进行介绍。

1.字符串复制

字符串复制是我们非常常用的操作之一。在字符串处理函数中包括strcpy函数,该函数也用于复制特定长度的字符串到另一个字符串中,一般形式如下:

strcpy(目的字符数组名,源字符数组名)

它可以将源字符数组中的字符串复制到目的字符数组种,字符串结束的标志“\0”也会一同复制。

这里有几点注意事项知道大家关注一下:
①.目的字符数组需要有足够的长度,否则无法全部装下所复制的字符串。
②.不能用赋值语句将一个字符串常量或者字符数组直接赋给一个字符数组。
③."目的字符串数组名"必须写成数组名形式,而“源字符数组名”可以是字符数组名,也可以是一个字符串常量。

2.字符串连接

顾名思义,字符串连接就是将一个字符串连接到另一个字符串的结尾,使其组合成一个新的字符串,strcat函数就具有这一功能,一般格式如下:

strcat(目的字符数组名,源字符数组名)

这个函数可以将源字符数组中的字符串连接到目的字符数组中字符串的后面,并删去目的字符数组中原有的结束标志“\0”。

3.字符串比较

字符串比较就是将一个字符串和另一个字符串从首字母开始进行比较(按照ASCII码的顺序进行比较)。在字符串处理函数中,strcmp函数就具有在字符串间进行比较的功能,一般形式如下:

strcmp(字符数组名 1,字符数组名 2)

它能实现按ASCII码顺序比较两个数组中的字符串的功能,并返回比较结果。

返回值结果如下:
①.字符串 1 = 字符串 2,返回值为0。
②.字符串 1 > 字符串 2,返回值为正数。
③.字符串 1 < 字符串 2,返回值为负数。

4.字符串大小写转换

字符串大小写转化要用到strupr和strlwr两个函数,strupr函数的一般形式下:

strupr(字符串)

它可以将字符串中的小写字母转换为大写字母,其他字母不变。

strlwr的一般形式如下:

strlwr(字符串)

与strupr相反,它能将字符串中的大写字母转换为小写字母,其他字母不变。

5.获得字符串的长度

在使用字符串的时候,我们有时需要动态获取字符串的长度,此时大家可能会想到使用循环来寻找"\0"的位置从而的到字符串的长度,但这一程序实现起来较为复杂,尤其是字符串长度非常大的时候,运算速度会大大降低。这时候strlen函数就可以用来计算字符串的长度,其一般形式如下:

strlen(字符串数组名)

它可以计算字符串的实际长度(不包括字符串结束标志“\0”),函数返回值为字符串的实际长度。

三、总结

本文介绍了数组的排序算法以及C语言标准库函数中常用的字符串处理函数的使用,加上上一篇博客介绍的一维数组、二维数组、字符数组以及多维数组的定义和引用,组合成了完整的数组知识模块,希望带大家有所帮助!

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shark-s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值