一维数组、二维数组详解、冒泡排序优化版

数组

数组有一维数组和二位数组的区分。
一维数组
我们定义一个一维数组arr[9]={1,2,3,4,5,6,7,8,9};
这里arr表示数组名,[]里面表示数组大小,{}里面是数组的内容。
这里如果我们不写数组大小,计算机就会根据我们的内容自动开辟。
在这里插入图片描述
那我们如何表示数组里面的每个元素呢?
例如数组元素的第一个元素 那就是 arr[0],数组元素的最后一个元素就是 arr[8]
在这里插入图片描述
从图中我们可以看到,数组好像是一块连续的区域,那它是不是连续的呢?我们实践一下!
在这里插入图片描述
从实践结果来看,一维数组在内存中连续存放的,且随着数组下标的增长,元素的地址也在有规律的增长。地址是由低到高!
二维数组
arr[3][4]={{1,2,3},{4,5}};
二维数组第一个下标表示行,第二个下标表示列。
二维数组的行可以省略,但是列不能省略。比如arr[][4]={{1,2,3},{4,5}};
那二维数组在空间中怎么表示?
![在这里插入图片描述](https://img-blog.csdnimg.cn/3a7e75fd400b4708bdf53ab56ccf663f.png
这样我们定义的二维数据就可视化的呈现出来了,如果我们要找到第二行第二列的元素,那就是表示为arr[1][1]。
上面我们提到,一维数组在内存中是连续的,那我们二维数组在内存中是连续的,我们依旧实践一下。
在这里插入图片描述
可以发现,二维数组在内存中依旧是连续的,并且第一行最后一列和第二行第一列的地址也是连续的,那我们换一种方式来思考,这样就会更加容易理解二维数组。
在这里插入图片描述
这样我们就可以把二维数组当成一维数组来理解,而他们的区别是一维数组下面就是一个格子,而我们的二位数组下面可以放很多格子,但是这些格子还隶属于他们的管辖范围,这样我们就更好的理解了二维数组。
下面我们用一个实际的案例来加深对数组的理解。
冒泡排序
假设我们有一个数组,定义为arr[]={5,2,7,4,9,8,1,3};现在我们对其排序。

#include <stdio.h>
void bubble(int arr[],int sz)
{
	int i=0,j=0,temp=0;
	for(i=0;i<sz-1;i++)
	{
		for(j=0;j<sz-1-i;j++)
		{
			if(arr[j]>arr[j+1])
			{
				temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			}
		}
	}
}
int main()
{
	int arr[]={5,2,7,4,8,9,1,3};
	int len = sizeof(arr)/sizeof(arr[0]);
	bubble(arr,len);
	for(int i=0;i<len;i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

这里需要讲解一个知识点,我们这个排序函数,传入的是两个参数,而不是一个参数,
我们可以试一下

#include <stdio.h>

void bubble(int arr[])
{
	int i = 0, j = 0, temp = 0;
	//那这里用一个指针来接收地址,算出来的大小就是4 
	//sizeof(arr[0])也是4 这样得到的结果就是1
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}
int main()
{
	int arr[] = { 5,2,7,4,8,9,1,3 };
	int len = sizeof(arr) / sizeof(arr[0]);
	//数组在传参的时候,传递的是arr首元素的地址 -->&arr[0]
	bubble(arr);
	for (int i= 0; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

在这里插入图片描述
我们可以看到最终的结果,并没有改变,那是什么原因呢?
这里我们就要讲一个知识点:
数组在传参的时候,实际上传递的是数组首元素的地址,而当我们用一个指针去接收这个地址的时候,算出来的指针大小也是4,这样就无法算出数组的长度,因此这样的求数组长度的方式是不可取的。因为我们必须在外面把数组的长度的算好,再把长度传进去。
这样我们的冒泡排序就完成了,但是我们仔细思考就会发现,这样的代码效率其实是比较低的,如果我一开始代码就是顺序的,但是它还是会一个一个在进行比较,因此我们对其进行优化。

冒泡排序优化版

#include <stdio.h>
void bubble(int arr[],int sz)
{
	int i=0,j=0,temp=0;
	for(i=0;i<sz-1;i++)
	{
		int flag=1;
		for(j=0;j<sz-1-i;j++)
		{
			if(arr[j]>arr[j+1])
			{
				temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
				flag=0;
			}
		}
		if(flag==1)
			break;
	}
}
int main()
{
	int arr[]={6,3,5,1,7,2,8,4,0,9};
	int len=sizeof(arr)/sizeof(arr[0]);
	bubble(arr,len);
	for(int i=0;i<len;i++)
	{
		printf("%d ",arr[i]);
	}
	return 0;
}

假设我们的数组是{9,0,2,8,4,6}
在这里插入图片描述
当我们第一次比较完了之后,就剩下前五个数进行比较了,当我们第二次比较完了之后就剩下前四个数进行比较了,但是此时已经是顺序了,因此我们加一个判断,当我们在经过一轮比较之后,没有任何的交换,那我们就认为这个数组已经是顺序了,就退出当前的循环,这样就大大的提高了代码的效率。
总结:
数组名是数组首元素的地址,但是有两个例外
1、sizeof(arr)–>此时数组名表示的整个数组,它计算的是整个数组的大小。(但是当数组在传参的时候,它传的是首地址,如果此时计算那就不是整个数组,就是我们上面的情况)。
2、&arr -->此时数组名代表整个数组,它取出的是整个数组的地址。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值