数组
是一组具有相同类型的变量的集合;
一维数组
#include<stdio.h>
int main()
{
int score[5];
int totalscore=0;
printf("input the scores of ten students:\n");
for(i=1;i<5;i++)
{
scanf("%d",&score[i]);
totalscore=totalscore+score[i];
}
printf("the average score is%f\n",totalscore/5.0);
return 0;
}
在定义数组时不能使用变量定义数组的大小
int score[n]/*这是非法的,即使n已被赋值也不行*/
对一维数组进行初始化时可以将元素初值放在=后面用一对花括号括起来的初始化列表中即
int score[5]={90,80,70,60,50};
初始化列表中提供的初值个数不能多余数组元素个数,若省略对组数长度的声明那么系统会自动按照初始化列表中提供的初值个数对数组进行初始化并确定数组的大小所以对数组的声明不能省略
int score[]={90,80,40,50,65};
b=编程实现显示用户输入的月份拥有的天数
#include<stdio.h>
#define MONETHS 12
int main()
{
int days[MONETHS]={31,28,31,30,31,30,31,31,30,31,30,31};
int month;
do{
printf("input a month:");
scanf("%d,&month");
}while(month<1||month>12);
printf("the number of days is %d\n",days[month-1]);
return 0;
}
为什么时[month-1]
因为数组days的下标是从0开始的
二维数组
类型 数组名[第一维长度][第二维长度];
short matrix[3][4];
matrix[0][0] | matrix[0][1] | matrix[0][2] | matrix[0][3] |
---|---|---|---|
matrix[1][0] | matrix[1][1] | matrix[1][2] | matrix[1][3] |
matrix[2][0] | matrix[2][1] | matrix[2][2] | matrix[2][3] |
三行四列
向函数传递一堆数组
若要把一个数组传递给一个函数,那么只要使用不带括号的数组名作为函数实参调用函数即可如Readscore(score,n);注意仅仅是数组名,不带方括号和下标。
int Average(int score[],int n)
表示函数Average()期望用形参score来接收一个数组,用形参n来指定数组的长度。
exercise:求一个3×3矩阵对角线元素之和。
#include <stdio.h>
int main()
{
int a[3][3];
int i,j,sum=0,sum1=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&a[i][j]);
}
}
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(i==j)
sum=sum+a[i][j];
if(i+j==2)
sum1=sum1+a[i][j];
}
}
printf("%d,%d",sum,sum1);
}
交换法排序
将第一个数分别与后面所有的数进行比较,若后面的数较大,则交换后面这个数和第一个数的位置;这一轮比较结束后,就求出了一个最大的数放在了第一个数的位置。然后进入第二轮比较。
选择法排序
#include <stdio.h>
void DataSort(int score[],int n)
{
int i,j,k,temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i+1;j<n;j++)
{
if(score[j]>score[k])
{
k-j;
}
}
if(k!=i)
{
temp=score[k];
score[k]=score[i];
score[i]=temp;
}
}
}
查找
1.1线性查找就是通过索引对数组data的每个元素进行遍历,如果发现要找的目标元素和数组data中的某个元素相同时,就返回已经查找到,当然,我们也是可以改进一下,就是直接把找到的元素返回即可。
1.2、二分查找法
二分查找法的效率比线性搜索法高,因为不用全部遍历一遍,节省了很多的时间,这里我们采用的方法是递归调用来进行查找的,如果发现中点位置的元素大小小于目标元素,就将中点位置的索引+1,进行递归调用,如果大于目标元素,就将中点位置索引-1,进行递归调用,而递归的出口就是,当中点位置的值和目标元素的值相等时,则返回结果。
1、顺序查找
学号 姓名 成绩
1001 ANN 93
1002 LILY 95
1003 LUCY 98
1004 TOM 100
编写一上程序,要求输出1001编号同学的具体信息
#include "stdio.h"
typedef struct student{
int id;//学生编号
char name[100];//学生姓名
float score ;//成绩
}Student; //这是个结构体
int search(Student stu[] , int n, int key)
{
int i;
for(i = 0 ; i<n ; i++)
if(stu[i].id ==key) //.id就是结构体里面的id
return i;//查询成功
return -1;//查询失败
}
void main()
{
Student stu[]={{1004, "TOM",100},
{1002 , "LILY",95},
{1001 , "ANN" , 93},
{1003, "LUCYr", 98}
};//初组化数组
int addr;//要查找的记录的地址
addr = search(stu ,4 , 1002);
printf("Student ID : %d\n", stu[addr].id);//输出查询找到的记录数据
printf("Student name :%s\n",stu[addr].name);
printf("Student score :%f\n",stu[addr].score);
}
2、半折查找
折半查找基本思想是:减小查找序列的长度,分而治之地进行关键字的查找。它的查找过程是:先确定待查找记录的所在的范围,然一逐渐缩小查找的范围,直至找到该记录为止(也可能查找失败)。例如文件记录的关键字序列为:
(1,3,5,6,9,12,13,17,21,28,30)
该序列包含11个元素,而且关键字单调递增。现在想查找关键字key为28的记录。如果应用顺序查找法进行,需要将28之前的所有关键字与key比较,共需比较10次。如果用折半查找方法可以这样帮
设指针low和high分别指向关键字序列的上界下界,即low = 0, high= 10.指针mid指向序列的中间位置,即mid=(low+high)/2=5.在这里low指向关键字1,high指向关键字30,mid指向关键字12.
(1)、首先将mid所指向的元素与key进行比较,因为key = 28,大于12,这就说明待查找的关键字一定位于mid之于mid与之间。这是因为原关键字序列是有递增的。因些下面的查找工作只需在[mid +1, high ]中进行。于是令指针low指向mid+1 的位置,即low =6 , 也就是指向关键字13,并将mid调整到指向关键字21,即mid = 8.
(2)、然后再将mid所指的元素key比较,因为key =28,大于21,说明待查找的关键字一定位于mid和之high之间。所以下面的查找工作仍然只需在[mid+1,high]中进行。于是令指针low指mid+! 的位置,即low =9 .high保持不变。
3)、按下来仍然将mid所指的元素与key进行比较,比较相等,查找成功,返回mid的值9。
int searce(keytype key[] ,int n , keytype k)
{
int low =0, high = n-1 , mid;
while(low <= high)
{
mid =(low + high)/2 ;
if(key [mid]==k)
return mid;//查询成功,返回mid
if(k>key[mid])
low = mid +1;//在后半序列中查找
else
high = mid -1//在前半序列中查找
}
return -1;//查找失败,返回-1
}