数组

数组的定义

在这里插入图片描述
在这里插入图片描述

练习

在这里插入图片描述

#include <stdio.h>
int main() {
	/*
		数组的定义格式:
			数据类型 数组名[长度]
	*/

	//1.定义数组存储全班8e位同学的年龄
	int arr1[80];
		
	//2.定义数组存储全班5@位同学的身高
	double arr2[50];
		
	//3.定义数组存储全身每件衣服的价格
	double arr3[3];
	
	return 0;
}

数组的初始化

在这里插入图片描述

练习

在这里插入图片描述

#include <stdio.h>
int main() {
	/*
		数组的定义并初始化的格式:
			数据类型 数组名[长度] = {数据1,数据2...};
		细节1:
			如果数组的长度没有写,数据值的个数就是数组的长度
		细节2:
			如果数组的长度已经写上,数据值的个数 <= 长度
			未赋值的部分有默认值
			整数:0
			小数:0.0
			字符:"\0'
			字符串:NULL(什么都没有)
	*/

	//1.定义数组存储5个学生的年龄,并初始化。
	int arr1[5] = {17,18,19,20,21};
	int arr2[] = {17,18,19,20,21};

	//2.定义数组存储你女朋友的身高,并初始化。
	double arr3[2] = {1.68,1.53};
	double arr4[] = {1.68,1.53};
	//如果我的两个女朋友的身高,我都不知道
	double arr5[2] = {0.0};
	
	return 0;
}

元素访问

索引

在这里插入图片描述

在这里插入图片描述

练习

#include <stdio.h>
int main() {
	/*
		需求:
			定义一个长度为5的数组,并进行初始化:1 2 3 4 5 
		完成下列要求:
			1.获取索引为0,2,4的元素,并求和
			2.把最后一个索引上的元素修改为10
	*/

	// 1.定义一个长度为5的数组,并进行初始化:1 2 3 4 5 
	int arr[] = {1,2,3,4,5};

	// 2.获取索引为0,2,4的元素,并求和
	int num1 = arr[0];
	int num2 = arr[2];
	int num3 = arr[4];
	int sum = num1 + num2 + num3;
	printf("%d\n",sum);//9

	// 3.把最后一个索引上的元素修改为10
	//索引的范围:最小索引 0
	//			最大索引 长度 - 1

	printf("%d\n", arr[4]);//5
	arr[4] = 10;
	printf("%d\n", arr[4]);//10
	
	return 0;
}

数组遍历

在这里插入图片描述

练习

#include <stdio.h>
int main() {
	/*
		需求:
			定义一个长度为5的数组,并进行初始化:1 2 3 4 5 
		完成下列要求:
			遍历数组,并把每一个元素打印到控制台
	*/

	// 1.定义一个长度为5的数组,并进行初始化:1 2 3 4 5 
	int arr[] = {1,2,3,4,5};

	// 2.获取
	//利用循环遍历数组
	for (int i = 0; i < 5; i++) {
		//i:依次表示数组里面的每一个素引
		printf("%d\n", arr[i]);
	}

	return 0;
}

内存中的变量、数组

内存

在这里插入图片描述
在这里插入图片描述

内存地址

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

内存中的变量

#include <stdio.h>
int main() {
	// 获取变量的内存地址
	int a = 10;
	printf("%p\n", &a); //0000006E05DAF594 十六进制
	return 0;
}

内存中的数组

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int main() {
	// 获取数组的内存地址
	int arr[] = {1,2,3};
	printf("%p\n", &arr);    //0000003B598FF8E8 数组的首地址(第一个元素,第一个格子的内存地址)
	printf("%p\n", &arr[0]); //0000003B598FF8E8 第一个元素内存地址
	// 索引:从内存的角度看 -> 偏移量(首地址 + 往后进行偏移)
	printf("%p\n", &arr[1]); //0000003B598FF8EC 偏移4个字节
	
	return 0; 
}

总结

在这里插入图片描述

思考

在这里插入图片描述
在这里插入图片描述

在底层实现上,计算机内存是线性的,每个内存单元都有一个唯一的地址。通过从0开始索引数组,可以通过简单的偏移量计算来访问数组的元素,因为数组的第一个元素的地址就是数组本身的地址加上0。

在这里插入图片描述

数组的常见问题

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
void printArr(int arr[],int len);
int main() {
	/*
		1.数组作为函数的参数,要注意什么?
			实际上传递是数组的首地址,如果要在函数中对数组进行遍历的话,记得一定要把数组的长度一起传递过去
			定义处:arr表示的就是完整的数组
			函数中的arr:只是一个变量,用来记录数组的首地址
			 
		2.数组的索引越界
			最小系引:8
			最大索引:长度 -1
	*/

	// 1.定义数组
	int arr[] = { 1,2,3,4,5 };
	//printf("%zu\n", sizeof(arr)); //20

	int len = sizeof(arr) / sizeof(int); //20
	//printf("%d ", arr[10]);索引越界

	// 2.调用函数遍历数组
	printArr(arr,len);
	return 0;
}
void printArr(int arr[],int len){
	//64位的操作系统当中,是以64个二进制表示内存地址值
	//printf("%zu\n", sizeof(arr)); //8
	for (int i = 0; i < len; i++) {
		printf("%d ", arr[i]);
	}
}

数组的算法题

求最值

在这里插入图片描述

#include <stdio.h>
int main() {
	/*
		思考一:
			循环是不是一定要从0索引开始?
			不是的,如果max的默认值记录的是e索引的,循环就可以从1开始,提高效率
		思考二:
			max的默认值是否可以写为0?
			不可以的,如果数组里面所有的数据都是负数,循环结束之后,得到的最大值0,此时会给别人产生误解
			max的默认值:一定要是数组中已经存在的数据,一般都是把0家引当做默认值
	*/

	// 1.定义数组
	int arr[] = {33,5 ,22,44,55};
	
	// 2.定义变量max,记录数组的最大值
	int max= arr[0];

	// 3.遍历数组得到每一个元素,拿着遍历到的元素跟max进行比较
	// 遍历到的元素 <= max里面记录的数据 不做任何处理
	// 遍历到的元素 > max里面记录的数据 max就要修改成新的值
	int len= sizeof(arr)/sizeof(int);
	for (int i = 0; i < len; i++) {
		if (arr[i] > max) {
			max = arr[i];
		}
	}

	// 4.输出max
	printf("%d\n", max);//55
	
	return 0;
}

求和

基础版

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
	// 1.定义数组
	int arr[10] = { 0 };
	int len = sizeof(arr) / sizeof(0);

	// 2.生成10个1~100之间的随机数存入数组
	// 设置种子
	srand(time(NULL));
	// 生成随机数
	for (int i = 0; i < len; i++) {
		int num = rand() % 100 + 1;
		// 把随机数存入到数组
		arr[i] = num;
	}

	// 3.利用累加思想求数组中所有数据的和
	int sum = 0;
	for (int i = 0; i < len; i++) {
		sum += arr[i];
	}
	//输出
	printf("%d\n", sum);

	return 0;
}

升级版

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int contains(int arr[], int len, int num);
int main() {
	// 1.定义数组
	int arr[10] = { 0 };
	int len = sizeof(arr) / sizeof(0);

	// 2.生成10个1~100之间的随机数存入数组
	// 设置种子
	srand(time(NULL));
	// 生成随机数
	for (int i = 0; i < len;) {
		int num = rand() % 100 + 1;
		//存入之前,先做一个判断,如果不存在,再进行添加
		int flag=contains(arr,len, num);
		if (!flag) {
			arr[i] = num;
			i++;
		}
	}

	for (int i = 0; i < len; i++) {
		printf("%d ",arr[i]);
	}
	printf("\n");

	// 3.利用累加思想求数组中所有数据的和
	int sum = 0;
	for (int i = 0; i < len; i++) {
		sum += arr[i];
	}
	
	// 4. 求平均数
	int avg = sum / len;

	// 5.统计有多少个数字比平均数小
	int count = 0;
	for (int i = 0; i < len; i++) {
		if (arr[i] < avg) {
			count++;
		}
	}

	// 6.输出
	printf("和为:%d\n", sum);
	printf("平均数为:%d\n", avg);
	printf("%d\n", count);

	return 0;
}

// 判断num在函数当中,是否存在
// 存在,返回1
// 不存在,返回0
int contains(int arr[],int len,int num) {
	for (int i = 0; i < len; i++) {
		// i:依次表示数组里面的每一个案引
		// arr[i]:依次表示数组里面的每一个数据
		if (arr[i] == num) {
			return 1;
		}
	}
		return 0;
}

反转数组

在这里插入图片描述

#include <stdio.h>
void printArr(int arr[], int len);
int main() {
	// 1.定义数组
	int arr[5] = { 0 };
	int len = sizeof(arr) / sizeof(0);

	// 2.键盘录入数据
	for (int i = 0; i < len; i++) {
		printf("请录入第%d个元素\n",i + 1); 
		scanf("%d", &arr[i]);
	}

	// 3.遍历数组
	printArr(arr, len);

	// 4.反转数组
	int i = 0; 
	int j = len - 1; 
	while (i < j) {
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
		i++;
		j--;
	}

	// 5.遍历数组
	printArr(arr, len);

	return 0;
}

void printArr(int arr[], int len) {
	for (int i = 0; i < len; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
}

打乱数据

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
	// 1.定义数组
	int arr[] = { 1,2,3,4,5 };
	int len = sizeof(arr) / sizeof(int);

	// 2.遍历数组,得到每一个元素,让这个元素跟随机索引处的元素进行交换
	// 设置种子
	srand(time(NULL));
	for (int i = 0; i < len; i++) {
		//获取一个随机索引
		// 0 ~ 4
		int index = rand() % len;
		// 拿着i指向的元素,跟index指向的元素进行交换
		int temp = arr[i];
		arr[i] = arr[index];
		arr[index] = temp;

		// 3.遍历数组
		for (int i = 0; i < len; i++) {
			printf("%d ", arr[i]);
		}
		return 0;
	}
}

常见算法

查找算法

在这里插入图片描述

基本查找/顺序查找

#include <stdio.h>
int order(int arr[], int len, int num);
int main() {
	/*
		需求:数组的基本查找/顺序查找
		核心思路:就是从数组的8索引开始,依次往后查找
				如果找到了,就会返回数据对应的索引
				如果没有找到,就会返回-1
	*/
	// 1.定义数组
	int arr[] = { 11,22,55,77,44 };
	int len = sizeof(arr) / sizeof(int);

	// 2.定义一个变量表示要查找的数据
	int num = 55;

	// 3.调用函数查找数据
	int index = order(arr,len, num);

	// 4.输出索引
	printf("%d\n", index);

	return 0;
}

//作用:查找数组中的数据//返回值:数据所在的索引
int order(int arr[], int len, int num) {
	for (int i = 0; i < len; i++)
		if (arr[i] == num) {
			return i;
		}
	return -1;
}

二分查找/折半查找

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int binarysearch(int arr[], int len, int num);
int main() {
	/*
		需求:数组的二分查找
		在7,23,79,81,103,127,131,147中查找数据
	*/

	// 1.定义数组
	int arr[] = { 7,23,79,81,103,127,131,147 };
	int len = sizeof(arr) / sizeof(int);

	// 2.定义变量表示要查找的数据
	int num  = 131;

	// 3.调用函数查找数据
	int index = binarysearch(arr, len, num);

	// 4.输出
	printf("%d\n", index);

}

// 作用:利用二分查找法查找数据
// 返回值:数据在数组中的索引
// 找到了,真实的索引
// 没有找到,返回 -1
int binarysearch(int arr[], int len, int num) {
	// 1.确定查找的范围
	int min = 0;
	int max = len - 1;
	//2.利用循环不断地进行查找
	while (min <= max) {
		// 确定中间位置
		int mid = (min + max) / 2;
		// 比较
		// min max mid 表示案引
		// num 表示要查找的元素
		// 坑:arr[mid]跟num 进行比较
		if (arr[mid] < num) {
			// 要查找的数据是在右边
			min = mid + 1;
		}
		else if (arr[mid] > num) {
			//要查找的数据是在左边
			max = mid - 1;
		}
		else {
			return mid;
		}
	}
	return -1;
}

总结

在这里插入图片描述

插值查找(二分查找改进)

在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述

分块查找

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

排序算法

冒泡排序

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int main() {
	/*
		需求:
			利用冒泡排序将下列数据按照从小到大的顺序进行排序
			3,5,2,1,4
	*/

	// 1.定义数组存储数据
	int arr[] = { 3,5,2,1,4 }; 
	int len = sizeof(arr) / sizeof(int);

	// 2.利用冒泡排序,把数组中的数据按照升序排列
	// 双重循环本质:就是把内循环重复执行了N次而已
	// 首先看内循环的作用
	// 
	// 内循环:找到本次循环的较大值,再把较大值放到了最右边
	// 外循环:把上面的这个动作重复执行了4次

	for (int i = 0; i < len - 1; i++) {
		for (int j = 0; j < len - 1 - i; j++) {
			//相邻的元素两两比较,小的在前面,大的后面
			if (arr[j] > arr[j + 1]) {
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
	for (int i = 0; i < len; i++) {
		printf("%d ", arr[i]);
	}
	return 0;
}

选择排序

在这里插入图片描述
在这里插入图片描述

#include <stdio.h>
int main() {
	/*
		需求:
			利用冒泡排序将下列数据按照从小到大的顺序进行排序
			3,5,2,1,4
	*/

	// 1.定义数组存储元素
	int arr[] = { 3,5,2,1,4 }; 
	int len = sizeof(arr) / sizeof(int);

	// 2.利用选择排序,把数组中的数据按照升序排列
	for (int i = 0; i < len - 1; i++) {
		//i:依次表示数组中的每一个索引
		// 第一轮:i = 8  j = 1 2 3 4
		// 第二轮:i = 1  j = 2 3 4
		// 第三轮:i = 2  j = 3 4
		// 第四轮:i = 3  j = 4
		for (int j = i + 1; j < len; j++) {
			//相邻的元素两两比较,小的在前面,大的后面
			if (arr[i] > arr[j]) {
				int temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
	}

	// 遍历
	for (int i = 0; i < len; i++) {
		printf("%d ", arr[i]);
	}
	return 0;
}
  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值