数组和常用算法

发布于 2021-05-17 12:19:10 字数 6057 浏览 1281 评论 0

理解 C 语言中的数组

数组是一个变量,由数组类型相同的一组元素组成

数组的结构和基本要素

  • 标识符:数组的名称,用于区分不同的数组
  • 数组元素:向数组中存放的数据
  • 元素下标:对数组元素进行编号
  • 元素类型:数组元素的数据类型

数组只有一个名称,及即标识符(用来表示数组的变量名)

元素下标标明了元素在数组中的位置,从0开始

数组重的每个元素都可以通过下标来访问

数组长度固定不变,避免数组越界

一维数组

语法

datatype arrayName[size];

初始化一维数组

//正确,后面的元素个数与声明的一致
int years[6] = {2012,2013,2014,2015,2016,2017};

//正确,后面的5个元素未初始化,默认值为0
int months[12] = {1,3,5,7,8,10,12};

//正确:元素个数为2
int days[] = {1,15};

//错误:未知元素个数
int array[] = {};

示例

#include <stdio.h>

/**
#数组的定义:类型 数组名[元素个数]
#eg: int a[5];//一个int 占用4个字符内存
#eg: char b[24];//一个char 占用1个字符内存
#eg: double c[3];//一个double 占用8个字符内存
#上面几个类型,都占用多少个字符的内存?(24)
#数组不能动态定义
*/
int main(){
  int s[10];
  int i,sum = 0;
  for(i=0;i<10;i++){
    printf("请输入第%d位同学的成绩:",i+1);
    scanf("%d",&s[i]);
    sum += s[i];
  }
  printf("成绩录入完毕,该次考试的平均分是:%.2f\n",(double)sum/10);
  return 0;
}

/*
#访问数组中的元素:数组名[下标]
#注意:数组的越界
*/

/*
# 数组的初始化
# 将数组中所有元素初始化为0-->int a[10] = {0};//事实上这里只是将第一个元素赋值为0
# 如果是赋予不同的值,那么用逗号分隔开即可-->int a[10] = {1,2,3,4,5,6,7,8,9,0}
# 你还可以只给一部分元素赋值,未被赋值的元素自动初始化为0-->int a[10] = {1,2,3,4,5,6}
# 有时候还可以偷懒,可以只给出各个元素的值,而不指定数组的长度(因为编译器会根据值的个数自动判断数组的长度)
# c99增加了一种新特性:指定初始化的元素。这样就可以只对数组中的某些指定元素进行初始化赋值,而未被赋值的原书自动初始化为0-->int a[10] = {[3]=1,[5]=3}
*/
int main(){
  int a[10] = {0};
  int b[10] = {1,2,3,4,5};
  int i;
  int j;

  for(i=0;i<10;i++){
    printf("第%d个元素的值为:%d\n",(i+1),a[i]);
  }

  for(j=0;j<10;j++){
    printf("第%d个元素的值为:%d\n",(j+1),b[j]);
  }
}

字符数组和字符串常量

# include <stdio.h>
# include <string.h>
//字符数组

/*
# 字符串常量:"FishC","小甲鱼","鱼C工作室"(一旦确认就不能改变)
# 字符数组:char a[] = {'',''}
*/
int main(){
  //初始化字符数组的每个元素
  char str1[] = {'F','i','s','h','C','\0'};

  //使用字符串常量初始化
  char str2[] = "FishC";

  //字符串处理函数(避免重新造轮子)
  //1、获取字符串的长度:strlen
  printf("sizeof str2 = %d\n",sizeof(str2));//包含'\0'
  printf("strlen str2 = %u\n",strlen(str2));
  //2、拷贝字符串:strcpy/strncpy

  //3、连接字符串:strcat/strncat

  //4、比较字符串:strcmp/strncmp

  return 0;
}

数组排序

1.冒泡排序

将相邻的两个数两两比较,每次外循环都将最大(最小)的数移到最后,如果后一个数小于(大于)前一个数,两个数交换。

#include <stdio.h>
int main(){
  int arr[8] = {9,5,6,12,1,3,18,11};
  int array_length = sizeof(arr)/sizeof(arr[0]);
  int i = 0,j = 0,tmp;
  for(int i = 0;i<(array_length-1);i++){
    for(int j = 0;j<(array_length-1-i);j++){
      if(arr[j]<arr[j+1]){
        tmp = arr[j];
        arr[j] = arr[j+1];
        arr[j+1] = tmp;
      }
    }
  }

  //打印排序过后的数组
  for(int k = 0;k<array_length;k++){
    printf("%d,",arr[k]);
  }
}

性能测试

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

unsigned long long a[50000000];
double maopao(unsigned long long a[],int n){
  int i,j,temp;
  clock_t beg,end;//起始时间和结束时间
  double time;
  beg = clock();
  for(i=0;i<n-1;i++){
    for(j=0;j<n-1-i;j++){
      if(a[j]<a[j-1]){
        temp = a[j];
        a[j] = a[j+1];
        a[j+1] = temp;
      }
    }
  }
  end = clock();
  time = (double)(end-beg);//CLOCKS_PER_SEC
  return time;//运行时间
}

int main(){
  int n,i;
  printf("请输入一个数:");
  scanf("%d",&n);
  srand(time(NULL));
  for(i=0;i<n;i++){//随机生成带牌数组
    a[i] = rand();
  }
  printf("冒泡排序运行时间%f\n",maopao(a,n));

  for(i=0;i<n;i++){
    a[i] = i;
  }
  printf("最好情况下,冒泡排序法表现如下:%f秒\n",maopao(a,n));

  for(i=0;i<n;i++){
    a[n-i-1] = i;
  }
  printf("最坏情况下,冒泡排序法表现如下:%f秒\n",maopao(a,n));
  return 0;
}

请输入一个数:100000\ 冒泡排序运行时间31747605.000000\ 最好情况下,冒泡排序法表现如下:23207438.000000秒\ 最坏情况下,冒泡排序法表现如下:34457264.000000秒

冒泡排序法是最慢的排序算法,实际运用中效率最低。

2.选择排序

每进行一次外循环都找到最大(最小)的数移到后面,每次内循环将最大的数与数组重的某个数比较,如果最大值小于(大于)那个数,将那个数的下标记录到max中。

#include <stdio.h>
int main(){
  int arr[8] = {9,5,6,12,1,3,18,11};
  int array_length = sizeof(arr)/sizeof(arr[0]);
  int temp,max;
  for(int i = 0;i<(array_length-1);i++){
    max = 0;//每次外循环都认为第一个元素为最大的
    for(int j = 1;j<(array_length-i);j++){
      if(arr[max]<arr[j]){
        max = j;
      }
    }
    temp = arr[max];
    arr[max] = arr[array_length-1-i];
    arr[array_length-1-i] = temp;
  }

  //打印排序过后的数组
  for(int k = 0;k<array_length;k++){
    printf("%d,",arr[k]);
  }
  printf("\n");
}

选择排序和冒泡排序差不多,使用较少

3.插入排序法

从第二个数开始,与已拍好的序列的周后哟个数比较,如果其值小雨最后一个数,则与前一个数比较,找到小于它的数,将其插入到这个数后面

#include <stdio.h>
int main(){
  int arr[8] = {9,5,6,12,1,3,18,11};
  int array_length = sizeof(arr)/sizeof(arr[0]);
  int temp;
  for(int i = 1;i<array_length;i++){
    temp = arr[i];
    for(int j = i-1 ;j>=0;j--){
      if(temp > arr[j]){
        arr[j+1] = arr[j];
        arr[j] = temp;
      }
    }
  }

  //打印排序过后的数组
  for(int k = 0;k<array_length;k++){
    printf("%d,",arr[k]);
  }
  printf("\n");
}

二维数组

语法

datatype name[rowSize][colSize];

#include <stdio.h>

//二维数组
/*
# 二维数组也叫做矩阵
# 二维数组的定义:类型 数组名[常量表达式][常量表达式]
#eg: int a[6][6];
#eg: char b[4][5];
#eg: double c[6][3]

# 二维数组的访问:数组名[下标][下标]
# 注意数组的越界

# 二维数组的初始化:由于二位数组在内存中是线性存放的,因此可以将所有的数据写在一个花括号内
#eg: int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}

# 为了更直观地表示元素的分布,可以用大括号将每一行的元素括起来
#eg: int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} }

# 二维数组也可以仅对一部分元素赋值

# 二维数组的初始化也可以偷懒,让编译器根据元素的数量计算数组的长度。但只有第1维的元素可以不写,其他维度必须写上
*/

int main(){
  int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
  int b[3][4] = {
    {1,2,3,4},
    {5,6,7,8},
    {9,10,11,12}
  };
  int i,j;
  for(i=0;i<3;i++){
    for(j=0;j<4;j++){
      printf("%d ",a[i][j]);
    }
    printf("\n");
  }
  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文