2021-10-26

c语言数组

#目录#

  1. 数组的创建
  2. 数组的初始化
  3. 数组的应用

1.数组的创建

数组创建:数组在创建时,必须定义好数据类型和数组大小 (注意大小不可为零),数组中的元素类型统一。
eg.

int arr[5]; //类型说明符 数组名[整数数型常量或表达式]
//此处定义了一个整数型一维数组,数组名为 arr ,包含6个元素

注意:数组的下标总是从0开始,即arr[0],arr[1],arr[3]等等

除了一维数组之外,数组还有二维、三维甚至多维,其定义如下:

//二维数组的定义
int arr[3][5];
//*该数组是指 数组arr中含有三个元素,每个元素含有5个元素,即每个元素又是包含5个元素的数组*//

//同理,看三位数组的定义
int arr[3][4][6];
//*数组arr中含有三个数组,每个元素又是含有四个元素的数组,这中的元素又是含有六个元素的数组*//

//多维数组,以此类推

以图形来形象表示
(一维数组就不多加赘述)
二维数组以表格来理解
在这里插入图片描述
三维数组为如下图示
三维数组


数组的初始化

在创建时就应该进行。

//允许形式:
int arr1[4] = {1, 2, 3, 4};
int arr2[] = {1, 2, 3, 4};//默认数组大小为4
int arr3[4] = {1, 2, 3};//部分赋初值,默认arr3[3]=0
int arr4[4] = {0};//数组初值均为0
char arr5[2] = {‘a’, 98};//arr5[1]中的元素为‘b'

//不允许形式
int arr6[2] = {1, 2, 3};

2.数组的应用

i.找最大数和最小数

即通过for语句对各个数组里的数据进行比较,找到最大数和最小数。

#include <stdio.h>

int main(){
    int min=1000; max=0;
    int a[100];
    for(int i=0; i<100; i++){
       if(scanf(%d”, &a[i])>max){
          max = a[i];
       }
       if(a[i]<min){
          min = a[i];
       }
    }
    printf(%d %d”, max, min);
    return 0;
}

ii.排序

此处主要介绍冒泡排序。

冒泡排序
  • 冒泡排序的普通程序

冒泡排序主要思路:对n-1个数据分别进行比较与交换。此处距离从右向前冒泡,即从第n个数据开始,将第a[n]与a[n-1]比较,若a[n]更小则交换两者的位置,以此类推,在第一次循环中将最小的数据放置于第一个位置即a[0],在不考虑其他条件的情况下,x次循环可以有序排列前x个数。全部循环结束后,将所有数据有序排列。

e.g

for (int i=0; i<n-1; i++){ //*共进行n-1次循环*//
      for (int j=n-1; j>=i+1; j--){ //*共进行n-i-1次比较*//
        if ( arr[j] < arr[j-1]){ //*此处为将数据以升序排序*//
        //*利用t来进行数据交换*//
             t = arr[j];
             arr[j] = arr[j-1];
             arr[j-1] = t;
         }
      }
    }

数据交换的另一种形式:

arr[j]+=arr[j-1];
arr[j-1]=arr[j]-arr[j-1];
arr[j]=arr[j]-arr[j-1];
  • 冒泡排序的优化

在冒泡排序中,如果此次冒泡并未发生数组的交换,那么可以说明,该位子一侧的数据已经为有序数据,而另一侧仍然是无序。在程序中设置一个变量flag来判断是否进行了数据交换。

for (int i=0; i<n; i++){
       flag=0;
        for (int j=n-1; j>=i+1; j--){
            if ( arr[j] < arr[j-1]){
                t = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = t;
                flag = 1; //*flag=1说明此时进行了交换*//
             }
             if(flag==0){
                   return;//*flag=0说明没有进行交换,推出循环*//
             }
        }
    }
  • 冒泡排序的再优化
    分析:除了前面所提到的flag外,如若在冒泡排序进行的过程中,在一个位置j之后的数据均已有序,即这部分数据可不参与排序,设置一个变量k,来记录有序数据的最终位置,以减少冒泡次数。
int k=n-1
for (int i=0; i<n; i++){
     flag=0;
     for (int j=n-1; j>=k; j--){
         if ( arr[j] < arr[j-1]){
             t = arr[j];
             arr[j] = arr[j-1];
             arr[j-1] = t;
             flag = 1;
             k=j-1;
             }
             if(flag==0){
             return;
             }
        }
    }
  • 排序的简单应用

题目简述:老师要对班级的成绩进行排名,输入班级的人数并输入每个人的成绩,输出从低到高的成绩排名。

#include <stdio.h>

int main(){
    int num;
    printf("请输入班级人数: ");
    scanf("%d", &num);
    printf("%d\n", num);
    int n = num;
    int arr[num];
    printf("请输入班级成绩: ");
    int i = 0;
    while ( scanf("%d", &arr[i]) && num >1){
        i++;
        num--;
    }
    for (int x=0; x<n; x++){
        printf("%3d", arr[x]);
        if( x == n-1) printf("\n");
    }//*输出未排序的数据*//
    printf("排序后成绩");
    int t;
    for (int i=0; i<n; i++){
        for (int j=n-1; j>=i+1; j--){
            if ( arr[j] < arr[j-1]){
                t = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = t;
             }
        }
    }//*用冒泡排序的思路对成绩进行升序排序*//
    for (int y=0; y<n; y++){
        printf("%3d", arr[y]);
    }//*排序后输出*//
    
    return 0;
}

iii.对分查找

分析:在一组有序的数组中,数组长度为n,从数组中间的开始寻找,设置i=0,j=n-1,来记录查找的范围。每次查找都查找范围中的中间值。若大于中间值则根据数组是升序还是降序,对i的值和j的值进行变换。

//*省略数组的读入和排序,假设该数组为升序*//
int num;
scanf(%d”, &num);
int i=0; j=n-1;
int mid;
while(i<=j){
   mid =(i+j)/2;
   if(a[mid]>num){
      j=mid-1;
   }
   else if(a[mid]<num){
     i=mid+1
   }
   else{
     pos=mid;
   }
}
printf(%d的位置应该为%d”, num, pos);

以上查找的是与输入数据相同时,数据的具体位置


若输入的数为num,如何查找不大于num的最小数以及不小于num的最大数?

int num;
scanf(%d”, &num);
int i=0; j=n-1;
while(i<=j){
    if(a[mid]>num){ //*if(a[mid]<num) i=mid+1;*//
      j=mid-1;
    }
    else{
      i=mid+1; //*j=mid-1*//
    }
}
printf(“不大于%d的最小数为%d”, num, a[i]);
//*printf(“不小于%d的最大数为%d“, num, a[j]);*//
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值