C语言系列(11)——数组(02)

一、一维数组最值(最大值max、最小值mix)

思路:

  • 定义一个变量比如max,赋值为数组第一个元素。max=arr[0];
  • 循环遍历数组。
  • 判断max和arr[i]的值,如果arr[i]大于max,则max=arr[i];
  • 直至循环结束,打印max的值。

图示:
数组求最值
代码: 求数组最大值

int arr[10] = { 1,6,3,99,55,66,13,64,200,111 };
int max = arr[0];// 赋值为数组第一个元素。
int i = 0;
//sizeof(arr)/sizeof(arr[0]) 获取数组元素个数
for (i = 1; i < sizeof(arr)/sizeof(arr[0]); i++)
{
    if (arr[i] > max) // 如果arr[i]大于max,则max=arr[i];
    {
         max = arr[i];
    }
}

printf(“Max:%d\n”, max);
打印结果:Max:200

那如何得到数组中最小值呢?

二、一维数组逆序

思路:

  • 定义两个变量,一个赋值为下标0,一个赋值为最大下标值(元素个数-1)。
  • 循环进行收尾交换。
  • 循环次数为(数组元素个数/2)。

图示:
首位交换
代码:

int arr[10] = { 1,2,3,4,5,11,12,13,14,15 };
int i = 0, j = 0;
int tmp = 0;
int size = sizeof(arr) / sizeof(arr[0]);
j = size - 1;//最大小标
for ( i = 0; i < size / 2; i++,j--)
{
    //首位交换
    tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
}
// 循环打印数组中的值
for ( i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:15 14 13 12 11 5 4 3 2 1

三、一维数组中出现频率最高的元素

思路:

  • 用每一个元素都从头到尾与所有元素进行比较,出现相同的则count+1。
  • 用max记录最大的那个count,用number记录出现频率最高的值。
  • 需要使用到双层嵌套循环,第一层循环控制元素值;
  • 第二层循环计算元素出现次数;

图示:
在这里插入图片描述
在这里插入图片描述
依次类推循环

代码:

int arr[10] = { 1,4,8,3,6,8,9,9,1,8 };
int i, j;
int tmp, count = 0;//临时记录每一轮的值和每一轮的值出现的次数
Int max = 0;//记录最高次数
int number = 0;//记录最高次数出现的值
int size = sizeof(arr) / sizeof(arr[0]);
for ( i = 0; i < size; i++)
{
    tmp = arr[i];//控制每一轮计算个数的元素值。
    count = 0;//每轮开始前计数器清零
    for ( j = 0; j < size; j++)
    {
         //将tmp与数组中每一个元素比较并进行count计数
         if (tmp == arr[j])
         {
              count++;//相同则计数器+1
         }
    }
    if (max < count)//记录最高次数
    {
         max = count;//记录出现多少次
         number = tmp;//记录最多的数字
    }
}

printf("number:%d,出现了%d次\n", number, max);

打印结果:number:8,出现了3次

四、删除指定值。

如:

int arr[10] = {11,20,2,5,98,11,101,55,6,10};
int number =  11; // 指定被删除的值

上述数组中又两个11,删除后:
arr元素最终为:20,2,5,98,101,55,6,10

注意:数组大小不会变,即使11被删除,但是数组元素个数还是有10个。

思路: 循环变量数组,遇到与number相同的,就再循环将后面的元素前移动覆盖 。
图示:
覆盖前面元素
代码:

int arr[10] = { 11,20,2,5,98,11,101,55,6,11 };
int number = 11;
int i = 0, j = 0;
int size = sizeof(arr) / sizeof(arr[0]);
for ( i = 0; i < size; i++)
{
    if (number == arr[i])//找到了要删除的元素
    {
         //后面的元素往前移动
         for ( j = i; j < size-1; j++)
         {
              arr[j] = arr[j+1];//注意,这里会将数字范围外的不确定的元素赋值过来
         }
         arr[size - 1] = -1;//每移动一次,可以将最后一个位置重新赋值。
    }
}
//循环打印
for (i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:20 2 5 98 101 55 6 -1 -1 -1

五、新增元素

将一个给定的值,新增到一个有序数组中(前提,数组空间足够,不考虑越界)。

如:int arr[10] = {1,2,5,6,8,10,15,17,18}; // 10个空间,9个值,留一个新增
int insert =  9;

新增后arr则为:1 2 5 6 8 9 10 15 17 18

思路:

  • 先找到要插入的位置(下标)。
    将insert值,一一比较,找到下标
    在这里插入图片描述

  • 将目标位置(下标)往后的所有值,集体往后移动一个位置
    移动要注意覆盖问题,所以要从最后一个元素往后移动。
    在这里插入图片描述

代码:

int arr[10] = { 1,2,5,6,8,10,15,17,18 };
int insert = 9;
int i = 0;
int size = sizeof(arr) / sizeof(arr[0]);
Int flag = size-1;//默认插入到最后面
//先找到9应该插入到哪个位置,为了防止越界,预留出一个位置
for ( i = 0; i < size-1; i++)
{
    if (insert <= arr[i])//如果找到了位置,则记录
    {
         flag = i;
         break;
    }//如果没有找到位置,表示insert是已有序列中最大值,则插入到最后面
}
if (flag == size-1)//插入到最后就直接赋值
{
    arr[flag] = insert;
}
else
{
    //先将目标位置空出来,后面的序列往后移动
    for ( i = size-1; i >= flag; i--)
    {
         arr[i] = arr[i - 1];
    }
    arr[flag] = insert;//空出来之后再赋值
}
//循环打印
for ( i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:1 2 5 6 8 9 10 15 17 18

六、排序:将一个乱序数组,升序排序
  1. 冒泡排序: 两个数比较大小,较大的数下沉,较小的数冒起来。
  • 比较相邻的两个数据,如果第二个数小,就交换位置;
  • 从后向前两两比较,一直到比较最前两个数据。最终最小数被交换到起始的位置,这样一轮下来最小的值就交换到了数组的一个位置。
  • 继续重复上述过程,依次将第2.3…n-1个最小数排好位置。

图示:
冒泡排序
代码:

int arr[8] = { 42,20,17,13,28,14,23,15 };
int size = sizeof(arr) / sizeof(arr[0]);
int i, j, tmp;
for ( i = 0; i < size-1; i++)//需要冒泡的次数,每次冒泡出最小的值
{
    for (j = size-1; j > i; j--)//注意循环次数,冒泡出去的元素就不用再比较了
    {
         if (arr[j] < arr[j-1])//后一个比前一个小,就交换
         {
              tmp = arr[j];
              arr[j] = arr[j - 1];
              arr[j - 1] = tmp;
         }
    }
}
//循环打印
for (i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:13 14 15 17 20 23 28 42

  1. 选择排序: 选择最小的一个与目标位置进行交换。
  • 在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换
  • 第二次遍历n-2个数,找到最小的数值与第二个元素交换;
  • 第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。

图示:
选择排序

int arr[8] = { 42,20,17,13,28,14,23,15 };
int size = sizeof(arr) / sizeof(arr[0]);
int i, j, tmp, minIndex;
for ( i = 0; i < size-1; i++)
{
    minIndex = i;
    for ( j = i+1; j < size; j++)
    {
         if (arr[i] > arr[j])//找到最小下标的位置
         {
              minIndex = j;
         }
    }
    if (minIndex != i)//如果最小的下标不是当前的下标,则交换
    {
         tmp = arr[i];
         arr[i] = arr[minIndex];
         arr[minIndex] = tmp;
    }
}
//循环打印
for (i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:13 14 15 17 20 23 28 42

  1. 插入排序:
    在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

图示:
插入排序

int arr[8] = { 42,20,17,13,28,14,23,15 };
int size = sizeof(arr) / sizeof(arr[0]);
int i, j, tmp;
for ( i = 0; i < size-1; i++)
{
    for ( j = i+1; j > 0; j--)
    {
         if (arr[j] < arr[j-1])
         {
              tmp = arr[j];
              arr[j] = arr[j - 1];
              arr[j - 1] = tmp;
         }
         else//注意:如果后一个比前一个不小,不用再继续循环,因为前面都是有序的
         {
              break;
         }
    }
}
//循环打印
for (i = 0; i < size; i++)
{
    printf("%d  ", arr[i]);
}

打印结果:13 14 15 17 20 23 28 42

总结:数组应用旨在训练童鞋们对数组的熟练运用,在脑海中要有一个空间思维,想象着各个元素之间的交换,移动,覆盖等;并注意访问越界问题。
上示例若能理解清楚并实现,表示对数组的理解已经达到了一定的高度。

练习:

1、从键盘中输入一个字符串,统计其字母(a~z ,A~Z)和数字(0~9)的个数。
2、从键盘中输入一个字符串(全数字),将其转换为整数后输出,“123”->123。
3、输入两个字符串,进行比较,如果字符全一致则输出相等,否则输出第一个不同字符的差。
4、他手里握着一叠扑克牌:A,2,....J,Q,K 一共13张。
	他先自己精心设计它们的顺序,然后正面朝下拿着,开始表演。
	只见他先从最下面拿一张放到最上面,再从最下面拿一张翻开放桌子上,是A;
	然后再从最下面拿一张放到最上面,再从最下面拿一张翻开放桌子上,是2;
	......如此循环直到手中只有一张牌,翻开放桌子上,刚好是K。这时,桌上牌的顺序是:
	A,2,3,4,5,6,7,8,9,10,J,Q,K (可用0表示10)请你计算一下,小明最开始的时候手里牌的顺序是怎样的。
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值