zoukankan      html  css  js  c++  java
  • 数组的顺序存储和实现

      对于数组A,一旦给定其维数n及各维长度bi(1≤i≤n),则该数组中元素的个数是固定的,不能对数组做插入和删除操作,不涉及移动数据元素操作,因此对于数组而言,采用顺序存储方式比较合适。

        我们知道,计算机内存器的结构是一维的,因此对于一维数组按下标顺序分配即可,而对多维数组,就必须按照某种次序,将数据元素排成一个线性序列,然后将这个线性序列存放在存储器中。

        数组的顺序存储结构有两种:一是以行为主序(或先行后列)的顺序存放,如BASIC、PASCAL、COBOL、C等程序设计语言中用的是以行为主的顺序分配,即一行分配完了接着分配下一行。另一种是以列为主序(先列后行)的顺序存放,如FORTRAN语言中,用的是以列为主序的分配顺序,即一列一列地分配。以行为主序的分配规律是:最右边的下标先变化,即最右下标从小到大,循环一遍后,右边第二个下标再变,…,从右向左,最后是左下标。以列为主序分配的规律恰好相反:最左边的下标先变化,即最左下标从小到大,循环一遍后,左边第二个下标再变,…,从左向右,最后是右下标。

        例如,二维数组Am×n以行为主序的存储序列为:

    a00 ,a01 ,… ,a0,n-1 ,a10 ,a11 ,…,a1,n-1 ,…am-1,0 ,am-1,1 ,…am-1,n-1

        而以列为主序的存储序列为:

    a00 ,a10 ,… ,am-1,0 ,a01 ,a11 ,…,am-11 ,…a0,n-1 ,a1,n-1 ,…am-1,n-1

        例如一个2×3的二维数组,逻辑结构可以用图4-8(a)表示。以行为主序的内存映象如图4-8(b)所示。 分配顺序为:a00 ,a01 ,a02 ,a10 ,a11 ,a12 ; 以列为主序的分配顺序为:a00 ,a10 ,a01 ,a11 ,a02  ,a12  ;它的内存映象如图4-8(c)所示。

    1

    图4-8 2×3数组存储(a)逻辑状态(b)以行为主序(c)以列为主序

        假设有一个3×4×2的三维数组A,共有24个元素,其逻辑结构如图4-9所示。

    2

    图4-9 三维数组的逻辑结构

        三维数组元素得标号由三个数字表示。如果对A3×4×2采用以行为主序的方式存放,则顺序为:

    a000 ,a001 ,a010 ,a011 ,… ,a220 ,a221 ,a230 ,a231

        采用以列为主序的方式存放,则顺序为:

    a000 ,a100 ,a200  ,a010 ,… ,a221 ,a031 ,a131 ,a231

        以上的存放规则可推广到多维数组的情况。总之,知道了多维数组的维数,以及每维的上下界,就可以方便地将多维数组按顺序存储结构存放在计算机中了。同时,根据数组的下标,可以计算出其在存储器中的位置。因此,数组的顺序存储是一种随机存取的结构。

        下面,以“以行为主序”的分配为例,讨论数组中数据元素存储位置的计算。

        设有二维数组Am×n,,下标从0开始,假设每个数组元素占size个存储单元,首元素a00的存储地址为LOC[0,0],对任意元素aij来说,因为aij是排在第i行,第j列,前面的i行有n×i个元素,第i行第j列个元素前面还有j个元素,所以,可得aij的地址计算公式如下:

    LOC[i,j] = LOC[0,0] + ( i×n + j ) × size

        同理,对三维数组Ar×m×n,可以看成是r个m×n的二维数组,若首元素的存储地址为LOC[0,0,0],则元素ai11的存储地址为LOC[i,1,1] = LOC[0,0,0] + ( i×m×n ) × size,这是因为在该元素之前,有i个m×n的二维数组。由ai11的地址和二维数组的地址计算公式,不难得到三维数组任意元素aijk的地址计算公式:

    LOC[i,j,k] = LOC[0,0,0] + ( i×m×n + j×n+k ) × size

    其中0≤i≤r-1,0≤j≤m-1,0≤k≤n-1。

        数组是各种高级语言中已经实现的数据结构。在高级语言的应用层上,一般不会涉及到数据元素的存储地址的计算,这一计算内存地址的任务是由高级语言的编译系统完成的。当我们使用数组进行程序设计时,只需给出数组的下标范围,编译系统将根据用户提供的必要参数进行地址分配,存取数据元素时,也只要给出下标,而不必考虑其内存情况。

        例4-1  若矩阵Am×n 中存在某个元素aij满足:aij是第i行中最小值且是第j列中的最大值,则称该元素为矩阵A的一个鞍点。试编写一个算法,找出A中的所有鞍点。

        基本思想:在矩阵A中求出每一行的最小值元素,然后判断该元素它是否是它所在列中的最大值,是则打印出,接着处理下一行。矩阵A用一个二维数组表示。

    算法如下:

    void  saddle (int A[ ][ ],int m, int n)        //m,n是矩阵A的行和列

    { int i,j,min;

      for (i=0;i

        { min=A[i][0]

               for (j=1; j

               if (A[i][j]

               for (j=0; j

    if (A[I][j]==min )

      { k=j;  p=0;

        while (p

            p++;

        if ( p>=m) printf ("%d,%d,%d\n", i ,k,min);

      } 

              }

  • 相关阅读:
    flutter doctor出现问题 [!] Android toolchain
    CSS中的cursor属性
    致蝙蝠侠阿卡姆三部曲——最伟大的改编游戏
    ajax的使用:例题、ajax的数据处理
    用ajax对数据进行删除和查看
    ThinkPhp框架:验证码功能
    ThinkPhp框架:父类及表单验证
    ThinkPhp框架:分页查询和补充框架知识
    ThinkPhp框架对“数据库”的基本操作
    ThinkPHP框架知识的注意点
  • 原文地址:https://www.cnblogs.com/nickchan/p/3104384.html
Copyright © 2011-2022 走看看