数组介绍

 

 

概念:什么是数组?

  数组就是若干个有序的相同数据类型的元素的集合。

  数组是构造类型,数组元素既可以是基本数据类型也可以是构造类型。例如二维数组或者多维数组,数组元素本身也是个数组,也就是构造类型数据。

数组的分类;

  按存储元素的类型:

    1. 数值数组

    2. 字符数组

    3. 指针数组

    4. 结构数组(用来存放一个结构体类型的数据)

  按照数组的维度:

    1. 一维数组

    2. 两位数组

    3. 多维数组

一维数组的定义:

  类型修饰符 数祖名[常量表达式];

注意事项:

  1. 数组长度可以是常量或者常量表达式,但不能是变量或者变量表达式(C99标准)。虽然XCODE可以定义数组时使用变量作为数组长度,但不建议这样使用。

  2. 数组的命名规则严格按照标识符的命名规则

  3. 数祖名不能和其他变量名同名

  4. 数祖名的长度可以使用宏定义

一维数组的初始化:

  1. 定义时初始化

    a. 完全初始化

    b. 部分初始化

  2. 先定义后初始化

注意点:  

  *1. 定义时初始化,未初始化的部分自动初始为0

  *2. 定义时初始化,如果数组长度是一个变量或者变量表达式,则不允许该数组定义时初始化。例如: int leng = 4; int arr[leng] = {1, 2, 3, 4}; 这样是错误的。

  *3. 数组没有初始化,数组元素也是有值的,不过值不确定,是个垃圾值。

  *4. 先定义后初始化的数组,随后进行的了部分初始化,未被初始化的那部分元素中的值仍为垃圾值。 

 

数组的引用

  数组元素作为变量使用。数组元素标识: 数祖名[元素下标]

  数组元素的标号从0开始,所以长度为n的数组,数组下标范围是0到n-1

数组的存储方式:

  #1 计算机会给数组分配一块联系的内存空间

  #2 数祖名代表数组的首地址(数祖名是一个常量,存放的就是数组的(首)地址),从首地址位置,依次存入数组的第1个、第2个、。。。、第n个元素

  #3 每个元素占用相同的空间大小(字节数)

  #4 元素之间的地址是连续的

一维数组长度的计算:

  数组在内存中占用的字节数:sizeof(数组名)

  数组的长度 = 数组的总字节数 / 数组元素类型占用字节数 = sizeof(数组名) / sizeof(元素类型)

 

数组元素作为函数参数

  和普通变量作为参数传递给函数一样。

  把数组元素的值作为实参传递给函数,是单向传递的过程。

 

用数组名作为函数参数

  作为实参传递:地址传递,将数组的地址传递函数的形参数组,两个数组共享一段内存空间。

 

  作为形参,可以不写数组长度。如果是多维函数可以不写第一维长度可以不写。

 

  形参和实参的类型必须一致。

  注意:形参和实参的长度可以不相同,因为编译的时候不会检查数组长度,可以编译通过,但运行结果可能和实际不相符。

Bubble sort:

  从开始第一个元素依次和后面的元素比较,把较大(或者较小)的元素和第一个元素交换。执行到最后一个元素后,第一个元素即最大值(或者最小值)。再从第二个元素和后面的元素比较;重复执行这样的循环直到倒数第二个元素比较完成后(因为最后一个元素一定是最小值(或者最大值),不用排序了),数组排序完成。

循环执行 n - 1次,比较了(n - 1) + (n - 2) + (n - 3) + … +1次。

// bubble sort

    for (int i = 0; i < length - 1; i++) {

        for (int j = 0; j < length - 1 - i; j++) {

            if (arr[j] > arr[j + 1]) {

                int temp = arr[j]; 

                arr[j] = arr[j + 1];

                arr[j + 1] = temp;

            }

        }

    }

 

 

Selection sort:

  在序列中找到最小(最大)元素,放到序列的起始位置arr[0];再从剩下的未排序的序列中找出最小元素,放到未排序的序列的起始位置arr[1];依次执行该循环直到排序完成。

  外循环负责排序,执行了n -1次;(i = 0 ; i < n -1 ; i++)  

  内循环负责比较及交换元素,每次循环执行n -1 - i次。i 这里指外部循环中的i。

 

// seleciton sort arr[]

    for (int i = 0; i < length - 1 ; i++) {

        for (int j = i + 1; j < length; j++) {

            if (arr[i] > arr[j]) {

                arr[i] = arr[i] ^ arr[j];

                arr[j] = arr[i] ^ arr[j];

                arr[i] = arr[i] ^ arr[j];

            }

        }

    }

 

 

Binary Search:

   如果数组中的元素是有序的,才可以使用折半查找。

  基本思路:

  在有序的数列中取中间元素作为比较对象,如果中间元素和要查找的关键字相等,则查找成功。如果不相等,则取可能包含关键字的那一半序列中的中间元素和关键字比较,重复这样的操作知道查找成功或者查找失败。

【步骤】

  1 low=1;high=length; // 设置初始区间
  2 low>high 时,返回查找失败信息// 表空,查找失败 

  3 lowhigh,mid=(low+high)/2; // 取中点

  a. 若key<arr[mid],high=mid-1;转2 // 查找在左半区进行 

  b. 若key>arr[mid],low=mid+1;转2 // 查找在右半区进行 

  c. 若key=arr[mid],返回数据元素在表中位置// 查找成功

数组定义时的其他注意事项:

  #1 如果定义数组时没有初始化,则必须指定数组的大小;

  #2 多维数组可以省略第一维的长度,但不能省略其他维的长度。

  #3 定义时部分初始化后,为初始化的元素,自动初始化为0

  #4 先定义再初始化,为初始化的元素,内容不确定。

二维数组的存储方式:

  1)计算机会给二维数组分配一块连续的存储空间

   2)数组名代表数组的首地址,从首地址位置,依次存入第1行、第2行、.....

   3)每一行存储方式,从行首地址还是,依次存储行的第1个元素、第2个元素、第3个元素......

   4)每个元素占用相同的字节数(取决于数组类型)

   5)并且数组中元素之间的地址是连续。

arr == &arr[0] == &arr[0][0]

int arr[3][4];

总计占用字节数: sizeof(arr);

每行占用字节数: sizeof(arr[0]);

行数: 总字节数/每行字节数 --> sizeof(arr)/sizeof(arr[0]);

列数: 行数/每个类型 --> sizeof(arr[0])/sizeof(int)

 1 /*
 2  有1000000个数,每个数取值范围是0-999999,找出其中重复的数。
 3  */
 4 //#define COUNT 1000000
 5 #define COUNT 1000000
 6 
 7 int main(void)
 8 {
 9     int a[COUNT] = {0};
10     for (int i = 0; i < COUNT; i++) {
11         int number = arc4random_uniform(COUNT)%COUNT;
12         //把随机数作为下标,值作为出现次数
13         a[number] ++;
14     }
15     //输出 重复的数字以及重复次数
16     for(int i = 0 ;i < COUNT;i++){
17         if (a[i] > 1) {
18             printf("%d repeats %d times\n",i,a[i]);
19         }
20     }
21     
22     for (int i = 0; i < COUNT; i++) {
23         printf("a[%d] = %d\t", i, a[i]);
24     }
25     return 0;
26 }

 

posted @ 2015-06-30 23:30  司英成·Owen  阅读(460)  评论(0编辑  收藏  举报