您的位置:首页 > 理论基础 > 数据结构算法

数据结构之——数组

2020-07-31 12:06 861 查看

数组

数组是顺序存储的随机存取结构,是其他数据结构实现顺序存储的基础。

一维数组的逻辑结构是线性表,多维数组是线性表的拓展。下面就让我们以二维数组为例,说明多维数组的逻辑结构、遍历和存储结构。

1.二维数组的逻辑结构

二维数组是一维数组的扩展,二维数组是“元素为一维数组”的一维数组。一个m行n列的二维数组,既可以看成由m个一维数组(行)所组成的线性表,也可以看成n个一维数组(列)所组成的线性表

其中,每个元素aij(-1<i<m,-1<j<n)同时属于两个线性表:第i行的线性表和第j列的线性表。具体分析如下:

(1)a0,0是起点,没有前驱;am-1,n-1是终点,没有后继。

(2)边界元素,a0,j和ai,0(0<i<m,0<j<n)只有一个前驱;am-1,j和ai,n-1(-1<i<m-1,-1<j<n-1)只有一个后继。

(3)ai,j(0<i<m-1,0<j<n-1)有两个前驱(行前驱ai-1,j和列前驱ai,j-1)和两个后继(行后继ai+1,j和列后继ai,j+1)。

同样,三维数组中的每个元素最多可以有三个前驱和三个后继。推广可知,m维数组的元素最多可以有m个前驱和m个后继。

2.二维数组的遍历

对二维数组进行遍历操作,有两种次序:行主序和列主序。

(1)行主序。以行序为主要次序,按行序递增访问数组每行,同一行按列序递增访问数组元素。

(2)列主序。以列序为主要次序,按列序递增访问数组每列,同一列按行序递增访问数组元素。

3.二维数组的存储结构

二维数组的存储结构,是由多个一维数组组合而成,组合方式有以下两种。

(1)二维数组的顺序存储结构

二维数组的顺序存储结构,将数组元素映射成线性关系存储,映射关系有行主列和列主序。存储结构如下图所示。采用一维数组连续存储二维数组的所有元素,将若干连续的存储单元在逻辑上划分成多个行/列。行主序或列主序由程序设计语言确定。

设二维数组有m行n列,Loc(a0,0)为二维数组的首地址,每个元素占c字节,元素ai,j的地址计算公式如下:

Loc(ai,j)=Loc(a0,0)+(i*n+j)*c //行主序

Loc(aj,i)=Loc(a0,0)+(j*m+i)*c //列主序

由此可见,二维数组元素地址是两个下标的线性函数,给定一对下标,无论行主序或列主序,计算地址花费的时间都是O(1),因此,二维数组也是随机存取结构

(2)二维数组的动态存储结构
二维数组所包含的多个一维数组可以分散存储,存储结构如下图所示。这也是随机存取结构,计算元素地址花费的时间是O(1)。

无论采用哪种存储结构,多维数组都是基于一维数组存储顶点,因此只能进行赋值、取值两种随机存取操作,不能进行插入、删除等。

4.Java语言的二维数组

Java语言的二维数组都是动态的,采用的引用模型如上图所示。

(1)声明和使用二维数组

声明二维数组变量并动态申请空间4行5列,语句如下:

int []element;				//声明二维数组变量,不能指定长度
element=new int[4][5]		//动态申请二维数组存储空间,元素已经初始化

声明时可为二维数组赋初值,将值用多层花括号括起来,例如:

int [] [] element={{1,2,3},{4,5,6}};

二维数组element由若干一维数组element[0]等组成,所以element和element[0]军均可以使用length属性表示数组长度,但含义不同。例如:

element.length			//返回二维数组的长度,即返回行数
element[0].length		//返回一维数组的长度,相当于列数

二维数组第i行第j列元素表示为element[i][j],i的取值范围是0~element.length-1,j的取值范围是0-element[i].length-1。

(2)不规则的二维数组

动态数组的存储结构比静态数组更灵活,所包含的多个一维数组可多次分别申请获得,还可以是不等长的。例如,多次申请二维数组存储空间过程如下所示:

(a)声明数组变量 int element[][];

(b)申请第一维的存储空间 element=new int[3][];

(c)申请第二维的存储空间 element[0]=new int[3]; element[1]=new int[4];

(3)二维数组可作为方法的参数和返回值

二维数组可以作为方法的参数和返回值,参数传递规则同赋值,即传递数组引用。例如:

void print(int element[][])		//二维数组作为方法的参数
int [] [] yanghui(int n)				//返回二维数组

应用——矩阵类

矩阵是工程设计中常用的数学对象。设A mn=[ai,j]是由mn个元素ai,j(-1<i<m,-1<j<n)组成的矩阵

在此处第一个元素为a0,0

矩阵运算主要有矩阵加、矩阵减、矩阵乘、矩阵转置等。设Bmn=[bi,j],C=[ci,j],Tmn=[ti,j],矩阵加、减、乘、转置运算定义如下:

设Cmn=Amn+Bmn,有ci,j=ai,j+bi,j。
设Cmn=Amn-Bmn,有ci,j=ai,j-bi,j。
设Tmn=Amn的矩阵转置,有ti,j=aj,i。
矩阵乘法参考如下:

由此我们可以声明矩阵类Matrix如下,其中成员变量rows、columns表示矩阵的行数和列数;二维数组element存储矩阵元素,elemeny[i][j]存储ai,j。

代码如下所示:

package Matrix;

public class Matrix {
private int rows,columns;		//矩阵行数、列数
private int[][] element;		//二维数组,存储矩阵元素
public Matrix(int m,int n) {	//构造m*n零矩阵。若m和n为负数,Java抛出负数组长度异常
this.element=new int[m][n];			//数组元素初值为0
this.rows=m;
this.columns=n;

}
public Matrix(int n) {
this(n,n);					//构造n*n零方方阵
}
public Matrix(int m,int n,int[][] value) {			//构造m*n矩阵,由value[][]提供元素
this(m,n);
for(int i=0;i<value.length&&i<m;i++) {			//value元素不足收获补0,忽略多余元素
for(int j=0;j<value[i].length&&j<n;j++) {
this.element[i][j]=value[i][j];
}

}

}
public int getRows() {		//返回矩阵行数
return this.rows;
}
public int getColumns() {	//返回矩阵列数
return this.columns;
}
public int get(int i,int j) {		//返回矩阵第i行第j列元素。若i、j越界,抛出序号越界异常
if(i>=0&&i<this.rows&&j>=0&&j<this.columns)
return this.element[i][j];
throw new IndexOutOfBoundsException("i="+i+",j="+j);

}
public void set(int i,int j,int x) {	//设置矩阵第i行j列元素为x
if(i>=0&&i<this.rows&&j>=0&&j<this.columns) {
this.element[i][j]=x;
}else {
throw new IndexOutOfBoundsException("i="+i+",j="+j);
}
}
public String toString() {			//返回矩阵元素描述字符串,行主序遍历
String str=" 矩阵"+this.getClass().getName()+"("+this.rows+"x"+this.columns+"):\n";
for(int i=0;i<this.rows;i++) {
for(int j=0;j<this.columns;j++) {
str+=String.format("%6d", this.element[i][j]);		//用"%6d"格式表示十进制整数占6列
}
str+="\n";

}
return str;

}
public static void main(String[] args) {
int value[] []= {{1,2,3},{4,5,6,7,8},{9}};
Matrix mata=new Matrix(3,5,value);
System.out.println("A"+mata.toString());
}

}

运行结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: