数组基础内容回顾
数组元素下标必须从零开始,且数组会开辟一块连续的空间。数组一旦开辟空间后大小不能改变,位置不能移动,此外数组名字就是数组的首地址,此处和指针联系较为紧密,因此此次和指针一块总结。
一维数组
一维数组的定义
类型 数组名[常量表达式];
一维数组初始化
初始化:创建变量的同时进行赋值,在初始化的时候会给没有赋值到值进行赋默认值0,此外当下标溢出时会赋随机值。
二维数组
类型 数组名[常量表达式1][常量表达式子2];
二维数组初始化
在初始化的时候,常量表达式2不能不指定长度,常量表达式1可以不指定长度。此外在二维数组中当大括号里面套大括号,一个大括号代表一行。
字符数组
char arr[]={"abc"};
a | b | c | \0 |
char arr[]={'a','b','c'};
a | b | c |
sizeof与strlen 区分
sizeof 在数组中直接计算所开辟空间的字节数
strlen 求的是字符串长度遇见“\0”停止
字符串处理函数
字符串比较函数,字符串不能通过运算符进行比较,可以通过strcmp进行比较
strcmp(字符数组或字符串,字符数组2或字符串2)
字符串复制函数,把2的字符串复制到1中
strcpy(字符数组或字符串,字符数组2或字符串2)
二分查找
#include<stdio.h>
int fun(int arr[], int k,int sz)//二分查找
{
int left = 0;
int right = sz - 1;
while (left <= right)//当left<right说明他们之间还有元素,当等于时说明要找的可能就是这个元素
{
// int mid = (left + right) / 2;
int mid=left+(right-left)/2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
return 1;//找不到时的标志
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k ;
printf("请输入你要查询的数字");
scanf("%d",&k);
int sz = sizeof(arr) / sizeof(arr[0]);
int i = fun(arr, k,sz);
if (i == 1)
{
printf("找不到这个数\n");
}
else
{
printf("找到了这个数%d,下标是%d",k,fun(arr, k,sz));
}
return 0;
}
二分查找的注意事项
二分查找只能用于有序的数组中,当数组不是有序的时候就无法比较。如一个数组{1,3,2,6,9,10,4,5,7,8},比如我们要找到是数字7的下标,此时的mid=9,k<mid,我们肯定会去左边寻找可是左边并没有7此时就是输出找不到,造成错误。
二分查找的算法
在有序的数组中,如int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
下面就以输入的数字k=6作为例子
首先我们求出mid的下标,然后找到数字中对应的值与我们输入数字进行对比
当k>arr[mid]时说明k在arr[mid]右侧
此时的left要更新为mid+1,然后对mid进行更新,mid=(left+right-1)/2
再次进行比较k<arr[mid]说明k在arr[mid]左侧
此时的right要更新为mid-1,然后对mid进行更新,mid=(left+right-1)/2此时的mid=5
这时k=arr[mid]说明找到了跳出循环
判断条件
当left<=right,当left<right说明他们之间还有元素,当等于时说明要找的可能就是这个元素
因此我在函数中设立了一个不成立的flag:return=1;
其他注意事项
我们会忽略一个溢出的问题:当这个数组无穷大的时候right和left都为max_int时肯定会溢出,定会对mid值造成影响,所以应对这个问题,我所作的是,多的减去少的,把多出的一半分给少的就可以解决这个问题了。
int mid=left+(right-left)/2;
总结
数组应用要多进行练习,尤其要牢记数组开辟的是一个连续的空间,这一点在指针应用较为广泛,具体的介绍下一篇文章在进行具体讲述。