概念:压缩存储的矩阵可以分为特殊矩阵和稀疏矩阵
对于那些具有相同元素或零元素在矩阵中分布具有一定规律的矩阵,被称之为特殊矩阵,而对于那些零元素数据远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称之为稀疏矩阵。
一、特殊矩阵
分类:
1、 对角矩阵(diagonal):M是一个对角矩阵当且仅当i!=j时有M(i,j)=0,如:
2 0 0 0
0 1 0 0
0 0 4 0
0 0 0 6
2、 三对角矩阵(tridiagonal):M是一个对三角矩阵当且仅当|i-j| >1时有M(i,j)= 0,如:
2 1 0 0
3 1 3 0
0 5 2 7
0 0 9 0
3、 下三角矩阵(lower tridiagonal):M是一个下三角矩阵当且仅当I <j时有m(i,j)=0.如:
2 0 0 0
5 1 0 0
4 3 1 0
4 2 7 0
4、 上三角矩阵(upper tridiagonal):M是一个上三角矩阵当且仅当I >j时有m(i,j)=0如:
2 1 3 1
0 1 3 8
0 0 1 6
0 0 0 7
5、 对称矩阵(symmetric):M是一个下对称矩阵当且仅当对于所有的i和j有m(i,j)=M(j,i)如:
2 4 6 0
4 1 9 5
6 9 4 7
0 5 7 0
注:对称矩阵又叫对称方阵:在一个n阶方阵A中,若元素满足Aij=Aji (0<=I,j<=n-1)则称其为n阶对称方阵。
特殊矩阵的压缩存储:
矩阵中相同的元素只分配一个存储空间,零元素不存储。
由于对称矩阵中的元素是关于主对角线对称的,为了节省空间,可以为每一对称元素只分配一个存储空间,存储时只存储对称矩阵中的上三角或者下三角中的元素。这样存储单元的总数是:
n*(n+1)/2----------------包含对角线上的元素时
K=
n*(n-1)/2----------------不包含对角线上的元素时
可以以行序为主进行压缩存储,也可以以列徐为主进行压缩存储。假设以行序为主进行压缩存储,可以用一个一位数组b[n*(n+1)/2]或者b[n*(n-1)/2]作为n阶对称矩阵A的存储结构,则b[k]和矩阵Aij之间存在如下对应关系:
i*(i+1)/2+j--------------当i>=j时
K= ---------------存储对角线上的元素时
j*(j+1)/2+i--------------当I < j时
i*(i-1)/2+j--------------当i>=j时
K= ---------------不存储对角线上的元素时
j*(j-1)/2+i--------------当I < j时
下面用特殊矩阵的压缩存储来解决一个实际问题:
package D0711; /* * 特殊矩阵的压缩存储---解决查询城市间距离的问题 * * 问题描述:六个城市分别为GN、JX、MI、OD、TL、TM * 将这六个城市从1-6进行编号。任意两个城市之间的距离可以用一个6*6的矩阵来表示。 * 矩阵的第i行和第i列代表第i个城市,distance(i,j)代表城市i和城市j之间的额距离。 * 由于对于所有的i和j有distance(i,j)=distance(j,i),所以该举证是一个对称矩阵。 * 根据该矩阵的特点,编程实现如下要求: * 1、两个城市之间的额距离只存储一次,自己到自己的距离不要存储。 * 2、当用户任意输入两个城市的名字,将显示这两个城市之间的距离。 * GN JX MI OD TL TM * GN 0 73 333 114 148 129 * JX 73 0 348 140 163 194 * MI 333 348 0 229 468 250 * OD 114 140 229 0 251 84 * TL 148 163 468 251 0 273 * TM 129 194 250 84 273 0 * * * * 分析: * 城市距离矩阵不用存储对角线元素,可用一个6*(6-1)/2 =15个数据元素的一位数组来存储 * */ import java.util.*; public class CityDistance { public static void main(String[] args) { int[] distance; String[] cityName = new String[] { "GN", "JX", "MI", "OD", "TL", "TM" }; int n, k; int i = 0, j = 0; System.out.println("请输入城市的数目:"); Scanner sc = new Scanner(System.in); n = sc.nextInt(); k = n * (n - 1) / 2;// 不要存储对角线元素 distance = new int[k]; System.out.println(" 请输入城市矩阵的下三角矩阵"); for (int m = 0; m < k; m++) { distance[m] = sc.nextInt(); } String temp; System.out.println(" 请输入开始城市简写名称:"); temp = sc.next(); for (int m = 0; m < n; m++) { if (cityName[m].equals(temp)) { i = m; break; } } String flag = ""; do { System.out.println("请输入目标城市简写名称:"); temp = sc.next(); for (int m = 0; m < n; m++) { if (cityName[m].equals(temp)) { j = m; break; } } int dis = i > j ? distance[i * (i - 1) / 2 + j] : distance[j * (j - 1) / 2 + i]; System.out.println(cityName[i] + " 到" + cityName[j] + "的距离是:" + dis); System.out.println("还要继续查询吗?(Y/N)"); flag = sc.next(); } while (flag.equals("y") || flag .equals("Y")); } } /* * 程序运行结果 * 请输入城市的数目: 6 请输入城市矩阵的下三角矩阵 73 333 348 114 140 229 148 163 468 251 129 194 250 84 273 请输入开始城市简写名称: GN 请输入目标城市简写名称: OD GN 到OD的距离是:114 还要继续查询吗?(Y/N) Y 请输入目标城市简写名称: GN GN 到GN的距离是:73 还要继续查询吗?(Y/N) y 请输入目标城市简写名称: TM GN 到TM的距离是:129 还要继续查询吗?(Y/N) * * */