跳转至

数组(冬二周+冬三周)

1.一维数组

定义注意点

C89不支持int a[n]的定义,方括号必须为常数

但C99支持

int a[5]={1,2,3}

对数组的部分元素定义时,未被定义的元素初值被赋值为0

int a[]={1,2,3,4,5}

数组初始化时,如果对全部元素都赋了初值,就可以省略数组长度。但是只对部分元素初始化时,数组长度不能省略

万能公式求数组长度

a_len=sizeof(a)/sizeof(a[0])

sizeof(a)表示a数组中全体元素的总宽度

2.数组排序算法

冒泡排序

int i,j,n,t;
for (i=0;i<n-1;i++)   #表示循环次数共n-1
{
   for (j=0;j<n-1-i;j++)    #比较次数
   {
       if (a[j]>a[j+1])
       {
          t=a[j];
          a[j]=a[j+1];
          a[j+1]=t;
       }
   }
}

每一轮把剩余元素的最大值冒泡分别到最后一个位置,倒数第二个位置,以此类推

选择排序

int i,j,k,t,n;
for (i=0;i<n-1;i++)
{
    k=i;
    for (j=i+1;j<n;j++)
    {
        if (a[j]<a[k])   //找到最小值下标
            k=j;
    }
    t=a[i];
    a[i]=a[k];
    a[k]=t   //交换
}

插入排序

#将a数组元素插入b数组中
int i,j,t,k,n,x,b[5],count;
for (i=0;i<n;i++)
{
    x=a[i];
    for (j=0;j<count;j++)  //count为b数组已有元素的个数
    {
        if (x<b[j])
            break;
    }
    for (k=count-1;k>=j;k--)
    {
        b[k+1]=b[k];
    }
    b[j]=x;
    count++;
}

找到插入位置后移位,往后移位时要从后往前

3.数组查找算法

二分查找

int left=0;
int right=n-1;
int mid=(left+right)/2;
While (left<=right && x!=a[mid])
{
    if (x<a[mid])
        right=mid-1;
    else
        left=mid+1;
    mid=(left+right)/2;
}
if (left<=right)
    printf("%d",mid);
else
    printf("not found");

4.二维数组

定义

short int a[3][4];    # 3表示行4表示列a[3][4]表示三行四列

a[0],a[1],...等为一维数组

内存连续性

在内存中,数组各个元素连续存放,内存的地址按照字节分配,数组a[0] [3] 的后面是a[1] [0],行优先存储。

假设a[0] [0]的地址为1000,即&a[0] [0]为1000,因为short int占用两个字节,所以a[0] [0]跨越1000和1001两个地址,由此推算出a[0] [3]的地址为1006

由于上述特性,当列索引越界时,如a[0] [4],这个元素看作a[0] [3]右边的元素,等价于a[1] [0]。这是右越界的情况。再来看左越界,a[1] [-1]可以等价为a[0] [3]

利用越界特性,可以用一重循环来赋值一个二维数组

二维数组边定义边赋值

short a[ ][2]={{1,2},{3,4},{5,6},{7,8}};   //定义了全部元素时,行号可以空心,列数不可以空心
int n=sizeof(a)/sizeof(a[0]);  //n=4,行数
n=sizeof(a)/sizeof(a[0][0]);   //n=8,总元素个数

初始化时,如果定义的二维数组能看出行数,则数组行号可以空心,列号在任何时候都不可以空心

如果只定义部分元素,行号和列号都不能省略,且未被初始化的元素初值为0