目录
相关题目练习(矩阵,冒泡排序,顺序查找,二分查找)
数组就是一种新的数据结构,可以看作是一种装数据的容器,为了方便一次性多装点数据,而开发出来的一种数据结构。
数组有个特点就是,一个数组只能装同一种数据,因为数据需要一定是确定数据类型,是不能放不同数据类型的数据的。学完数组后,其实字符串就是把字符放在数组里面,就成了字符串。
数组中的数据是有序的,可以通过下标来访问某个元素;数据是同质的,所有元素必须具有相同的数据类型。
数组特别要注意,赋值的时候,写得是数组的长度,例如int array[10]其中10是数组的长度,说明能放10个数。
数组是连续存储的,所以数组就有坐标,也叫做索引,数组的索引从0开始到数组的长度-1结束,如array[10]
其中第一个数据是array[0], 第十个数据是array[9]。
这个时候特别要注意数组长度和索引最大值不是一个概念。
一维数组相关笔记整理:
1.声明一维数组一般形式:数据类型 数组名[常量表达式]
"[ ]"是数组的标志,"[ ]"中的常量表达式表示数组元素个数,即数组长度,常量表达式必须是正整数。eg. int intArray[5];
大多数情况下用命名常量来指定数组长度,更容易调整数组长度。eg. 1.#define ARRAY_SIZE 5 2.int intArray[ARRAY_SIZE];
2.访问数组名方式:数组名[下标]。 访问数组时注意下标不能越界。
3.数组的初始化式只能在一条语句中完成数组声明和初始化。eg.int intArray[5]={1,2,3,4,5};
4.声明数组时,如果给定了数组的初始化式,则数组长度可以省略。
5.数组初始化式中初始值可以小于数组长度,数组前面的元素被初始化为数组初始化式中对应的初始值,剩余元素被初始化为0。
6.数组初始化式不能为空,初始值个数也不能大于数组长度。
7.C99中指定初始化方法:int intArray[20]={[2]=20,[9]=8}; 数组中intArray[2]=20,intArray[9]=8,其他元素为默认初始值0。
8.数组大小/数组元素大小=数组长度
9给数组元素赋值: for(i=0;i<ARRAY_SIZE;++i)
scanf("%d",&intArray[i]);
10.使用memset()函数给整体赋值,必须包含string.h头文件。eg.将intArray数组所有元素均赋值为0:memset(intArray,0,sizeof(intArray));
11.元素必须逐个进行复制,且目标函数(intSecondArray)长度大于或等于源数组(intArray)
eg. for(i=0;i<ARRAY_SIZE;i++)
intSecondArray[i]=intArray[i];
12.元素复制也可以使用标准函数库memcpy()进行复制。为了使用memcpy()函数,必须包含string.h头文件。
eg. memcpy(intSecondArray,intArray,sizeof(intArray));
二维数组相关笔记整理:
1.声明二维数组一般形式:
数组类型 数组名[常量表达式][常量表达式2];
eg. int intMatrix[3][2]; 声明了一个名为intMatrix、3行2列、有6个元素的二维数组,每个元素都是int类型
2.在声明二维数组式,可以使用嵌套的数组初始化式给数组元素赋初始值。
eg.int intMatrix[3][2]={(1,2),(3,4),(5,6)};
等价于: int intMatrix[3][2];
intMatrix[0][0]=1;
intMatrix[0][1]=2;
intMatrix[1][0]=3;
intMatrix[1][1]=4;
intMatrix[2][0]=5;
intMatrix[2][1]=6;
3.声明二维数组时,如果给定了初始化式,则数组行长度可以省略,但列长度不能省略。
4.数组初始化式不能为空,初始值个数也不能大于数组长度。
5.C99指定的初始化式对二维数组也有效。
数组定义方法:
以下数组的7种定义方法,一定要熟悉。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include "tools.c"
int main() {
// 单个赋值
int array[5];
array[0] = 10;
array[1] = 20;
array[2] = 30;
array[3] = 40;
array[4] = 50;
// printf("%d\n", array[0]);
// printf("%d\n", array[14]);
// 集体赋值
int array_1[5] = {11, 22, 33, 44, 55};
// printf("%d\n", array_1[0]);
// printf("%d\n", array_1[140]);
int array_2[5] = {1, 2, 3};
// printf("%d\n", array_2[0]);
// printf("%d\n", array_2[4]);
int array_3[5] = {0};
// printf("%d\n", array_3[0]);
// printf("%d\n", array_3[4]);
// int array_4[5] = {}; // 错误
// printf("%d\n", array_4[0]);
// int array_5[5] = {0, 1, 2, 3, 4, 5}; // 错误,超出数组存储数据的个数
int array_6[20] = {[2] = 22, [9] = 8, [14] = 58, [19] = 11};
// printf("%d\n", array_6[2]);
int array_7[20];
int i;
srand(time(NULL));
for(i=0; i<20; i++){
array_7[i] = 1 + rand() % 100;
}
return 0;
}
数组其实是比较简单的,一维数组可以看作是excel表格中的一行,二维数组可以看做excel表格中的一张表。还有就是数组的长度和索引(也叫做位置坐标)之间的关系。所以无论是一维数组还是二维数组,都是从0开始,到长度-1结束。
索引 | 0 | 1 | 2 | 3 | 4 |
Array | 100 | 200 | 300 | 400 | 500 |
索引 | 0 | 1 | 2 | 3 | 4 |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 6 | 7 | 8 | 9 | 10 |
2 | 11 | 12 | 13 | 14 | 15 |
3 | 16 | 17 | 18 | 19 | 20 |
4 | 21 | 22 | 23 | 24 | 25 |
数组类型:
以下列举了各种类型的数组:
数组重要知识点
数组就是个装数据的杯子,只是一次性可以装很多数据。要特别注意数组的赋值,数据的索引,数组的遍历(也就是打印数组),其实就是涉及到了循环和双重循环,那么双重循环我们在前面已经讲了很多了,画三角形和九九乘法表,都是用到双重循环,现在就是改头换面,但是代码没变,还是那些for循环代码。
要特别注意数组的赋值,数据的索引,数组的遍历(也就是打印数组)
数组作用:基本数据类型只能存放单个值,数组可以一次性放很多数据。
一个数组的数据在内存中是连续存放的。
数组就是一个容器,用来装数据的杯子。
大白话
1、赋值 把数据装进杯子
2、遍历 把数据倒出杯子,像数钱一样把数据一个个数出来 自己写的两个遍历函数
3、索引 数组是顺序存放,有坐标来指示每个数据位置
索引从0开始到 (长度-1)
数组的遍历:
一维数组遍历用for
二维数组遍历用双层for
下面多加一个可变长数组,这个可以选择性了解:
1.数组长度有时候可以使用非常量表达式(可变长数组)
eg. int n;
scanf("%d",&n);
int intArray[n];
2.可变长数组可以是多维的:
eg. int n,m;
scanf("%d%d",&n,&m);
int intArray[n][m];
3.可变长数组的长度可以用任意整型表达式指定
eg. int i,j,k;
...
int a[3*i+5];
int b[j+k];
4.可变长数组可以作为函数参数:
eg. void reverseArray(int array[],int n){
...
}
可变为:
void reverseArray(int n,int array[n]){
...
}
使用可变长数组参数,可以明确指定数组array的长度就是n。
5.二维数组作为函数参数时,也可以使用可变长数组参数:
eg. void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
...
}
可变为:
void transposeMatrix(int rowSize,int columnSize,int matrix[rowSize][columnSize]){
...
}
相关题目练习:
最后是关于数组的一些经典题目,我根据自己的理解加上一些注释,希望对大家有帮助,若有错误也希望伙伴们提出来哇!下面可以结合上面的笔记进行学习:
(1)创建一个自定义大小的矩阵,然后将矩阵进行行列互换:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ROW_SIZE 10 //宏定义数组行长度
#define COLUMN_SIZE 10 //宏定义数组列长度
void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize); //声明函数
void printMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize); //声明函数
int main(){
int matrix[ROW_SIZE][COLUMN_SIZE]; //声明数组及其大小 (最大行长度和最大列长度)
int row,column,n; //声明数组行和列和矩阵的大小(即有效长度)
printf("输入矩阵的大小:");
scanf("%d",&n);
srand(time(NULL));
for(row=0;row<n;++row){ //双重for循环为数组赋值
for(column=0;column<n;++column){
matrix[row][column]=10+rand()%90; //随机数填充数组matrix
}
}
printMatrix(matrix,n,n); //调用函数
transposeMatrix(matrix,n,n); //调用函数
printf("行列互换后的矩阵:\n");
printMatrix(matrix,n,n); //调用函数
return 0;
} //注意上面函数调用顺序
void transposeMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
int row,column,temp;
for(row=0;row<rowSize;++row){ //双重for循环进行数组行列互换
for(column=0;column<columnSize;++column){
if(row<column){
temp=matrix[row][column];
matrix[row][column]=matrix[column][row];
matrix[column][row]=temp;
}
}
}
}
void printMatrix(int matrix[][COLUMN_SIZE],int rowSize,int columnSize){
int row,column;
for(row=0;row<rowSize;++row){
for(column=0;column<columnSize-1;++column){ //columnSize-1在最后重新打印出来是因为要换行,所以格外打印
printf("%d ",matrix[row][column]);
}
printf("%d\n",matrix[row][columnSize-1]);
}
}
代码中的void transposeMatrix()和void printMatrix()其实可以认为是两个功能,将自己想要的功能补充完整,再在main函数中直接调用该功能(函数)。
运行结果:
输入矩阵大小:4
63 32 90 32
54 50 23 64
86 18 79 93
95 45 21 51
行列互换后:
63 54 86 95
32 50 18 45
90 23 79 21
32 64 93 51
程序每次运行的结果可能不同。
(2)下面是大家熟悉的冒泡排序(自己的注释可能有点多,是自己的理解,大家选择性地看哈):
#include <stdio.h>
#define ARRAY_SIZE 4
void bubbleSort(int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
int list[ARRAY_SIZE]={7,6,8,5};
printf("排序前:");
printArray(list,ARRAY_SIZE); //调用函数把原数组打印出来
bubbleSort(list,ARRAY_SIZE); //调用函数把原数组进行冒泡排序
printf("排序后:");
printArray(list,ARRAY_SIZE); //调用函数将冒泡排序后的数组打印出来
return 0;
}
void bubbleSort(int list[],int arraySize){
int pass,i,t,exchange;
for(pass=1;pass<arraySize;++pass){
exchange=0;
for(i=0;i<arraySize-pass;++i){
if(list[i]>list[i+1]){ //根据条件将元素位置进行交换
t=list[i];
list[i]=list[i+1];
list[i+1]=t;
exchange=1; //若前面满足条件执行到exchang=1后,返回++i继续循环,直到不满足for里面的条件才结束循环
}
} //for循环里面的元素
if(exchange==0) //对于一开始就不满足第二个for里面的条件的元素,直接跳出来
break;
}
}
void printArray(int list[],int arraySize){
int i;
for(i=0;i<arraySize-1;++i)
printf("%d",list[i]);
printf("%d\n",list[arraySize-1]); //换行
}
//对于for循环过程:当arraySize=4时
//当pass=1时,i<3 √, i++;
// lsit[i]>list[i+1] i=0时,i<3 √ list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// lsit[i]>list[i+1] i=1时,i<3 √ list[1]>list[2] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// lsit[i]>list[i+1] i=2时,i<3 √ list[2]>list[3] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// lsit[i]>list[i+1] i=3时,i<3不成立,结束循环,回到pass++
/*注意每次循环结束后同一下标的元素可能发生改变*/ //当pass=2时,i<2 √,i++;
/*即不同循环中的同一下标的元素不一样*/ // lsit[i]>list[i+1] i=0时,i<2 √ list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// lsit[i]>list[i+1] i=1时,i<2 √ list[1]>list[2] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// list[i]>list[i+1] i=2时,i<2不成立,结束循环,回到pass++
//当pass=时3,i<1 √,i++;
// lsit[i]>list[i+1] i=0时,i<1 √ list[0]>list[1] 成立则交换元素位置后回到++i继续循环(与下一位比较),否则直接跳到break结束跳出
// lsit[i]>list[i+1] i=1时,i<1不成立,结束循环,回到pass++
//当pass=4时,i<0 √,i++
// list[i]>list[i+1] i=0时,i<0不成立,结束循环
运行结果:
排序前:7 6 8 5
排序后:5 6 7 8
可以参考上图进行理解。
(3)顺序查找:顺序查找就是将要查找的元素(称为关键字)顺序与数组中的每个元素一一进行比较,直至关键字与数组某个元素匹配;或者与所有数组元素都比较完毕,未找到与关键字匹配的数组元素。
#include <stdio.h>
#define ARRAY_SIZE 10
int linearSearch(int key,int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
int key,index;
int list[ARRAY_SIZE]={1,4,4,2,5,-3,6,2,7,-8}; //数组list可容纳10个元素
printArray(list,ARRAY_SIZE); //调用函数输出数组list的值
printf("输入需要查找的值:");
scanf("%d",&key);
index=linearSearch(key,list,ARRAY_SIZE); //index表示的是该函数的返回值
if(index==-1)
printf("查找失败!\n");
else
printf("查找成功:%d位于数组下标%d位置",key,index);
return 0;
}
int linearSearch(int key,int list[],int arraySize){
int i;
for(i=0;i<arraySize;++i){ //通过for循环将key与数组list中的每个元素一一进行比较
if(key==list[i])
return i; //若找到匹配者,返回与关键字匹配的数组元素的下标
}
return -1; //若for循环没有找到满足条件的值,则最后返回-1
}
void printArray(int list[],int arraySize){
int i;
for(i=0;i<arraySize-1;++i)
printf("%d ",list[i]);
printf("%d\n",list[arraySize-1]);
}
(4)二分查找:二分查找与顺序查找只是查找的函数功能有变化,其他基本没变。
#include <stdio.h>
#define ARRAY_SIZE 13
int binarySearch(int key,int list[],int arraySize);
void printArray(int list[],int arraySize);
int main(){
int key,index;
int list[ARRAY_SIZE]={2,4,7,10,11,45,50,59,60,66,69,70,70};
printArray(list,ARRAY_SIZE);
printf("输入需要查找的值:");
scanf("%d",&key);
index=binarySearch(key,list,ARRAY_SIZE);
if(index<0)
printf("查找失败!\n");
else
printf("查找成功:%d位于数组下标%d位置",key,index);
return 0;
} //下标:0 1 2 3 4 5 6 7 8 9 10 11 12
int binarySearch(int key,int list[],int arraySize){ //{2 4 7 10 11 45 50 59 60 66 69 70 70}
int low,mid,high;
low=0;
high=arraySize-1;
while(low<=high){ /*查找11过程: */
mid=(low+high)/2; // 一开始low=0,high=12,所以mid=6 ,对应的list[6]=50不等于11,而50>11,所有往前查找;
if(key<list[mid]) // 此时,low=0,high=mid-1=5,mid=(low+high)/2=2.5,但mid的数据类型为int,所以mid=2,对应的list[2]=7<11,所以往后查找;
high=mid-1; // 此时,low=mid+1=3,high=5,所以 mid=(low+high)/2=4,对应的list[4]=11,所有11的位置即可得出,return mid
else if(key==list[mid])
return mid;
else
low=mid+1;
}
return -1; // 若数组里面的元素全部循环结束没有找到匹配的值,则返回-1
}
void printArray(int list[],int arraySize){
int i;
for(i=0;i<arraySize-1;++i)
printf("%d ",list[i]);
printf("%d\n",list[arraySize-1]);
}
运行结果:
2 4 7 10 11 45 5 59 60 66 69 70 70
输入需要查找的值:11
查找成功:11位于数组下标4位置
2 4 7 10 11 45 5 59 60 66 69 70 70
输入需要查找的值:12
查找失败!
数组笔记分享到这啦!
有错误欢迎批评指正哈!