当前位置:
文档之家› 数据结构第5章 数组和广义表
数据结构第5章 数组和广义表
(3)三元组元素赋值 对于稀疏矩阵A,执行A[i][j]=x。先在三元组表示的data 数组中找到适当的位臵k,若找到了这样的元素,直接将其d 值臵为x,否则将k~t.nums个元素后移一个位臵,将指定元 素x插入到data[k]中。当位臵错误时返回false。对应的算法如 下:
bool SMatrixClass::Setvalue(int i,int j,int x) //三元组元素赋值A[i][j]=x { int k=0,k1; if (i<0 || i>=rows || j<0 || j>=cols) return false; //下标错误时返回false while (k<nums && i>data[k].r) k++; //查找第i行的第一个非零元素 while (k<nums && i==data[k].r && j>data[k].c) k++; //在第i行中查找第j列的元素
if (data[k].r==i && data[k].c==j) //找到了这样的元素 data[k].d=x; else //不存在这样的元素时插入一个元素 { for (k1=nums-1; k1>=k;k1--) //后移元素以便插入 { data[k1+1].r=data[k1].r; data[k1+1].c=data[k1].c; data[k1+1].d=data[k1].d; } data[k].r=i; data[k].c=j; data[k].d=x; nums++; } return true; //赋值成功时返回true
(2)从一个二维稀疏矩阵创建其三元组表示 以行序方式扫描二维稀疏矩阵A,将其非零的元素插入到 三元组的data数组中。对应的算法如下:
void SMatrixClass::CreateTSMatrix(int A[][MAXC],int m,int n) //创建三元组 { int i,j; rows=m; cols=n; nums=0; for (i=0;i<m;i++) { for (j=0;j<n;j++) if (A[i][j]!=0) //只存储非零元素 { data[nums].r=i; data[nums].c=j; data[nums].d=A[i][j]; nums++数组中表示的非零元素通常以行序为主序 顺序排列,它是一种下标按行有序的存储结构。这种有序 存储结构可简化大多数稀疏矩阵运算算法。
(1)三元组顺序表的初始化和销毁 三元组顺序表的初始化和销毁分别通过构造函数和析构函 数来实现,对应的算法如下:
SMatrixClass::SMatrixClass() { data=new TupNode[MaxSize]; } SMatrixClass::~SMatrixClass() { delete [] data; } //构造函数 //分配空间 //析构函数 //释放空间
LOC(ai,j)=LOC(a1,1)+[(i-1)×n+(j-1)]×k
若采用以列序为主序的存储方式,即先存储第1列,然 后紧接着存储第2列,…,最后存储第n列。此时,二维数组 的线性排列次序为: a1,1,a2,1,…,am,1,a1,2,a2,2,…,am,2,…,a1,n,a2,n,…am,n
抽象数据类型d维数组定义如下:
5.1.2 数组的存储结构
数组通常采用顺序存储方式来实现。 一维数组的所有元素依逻辑次序存放在一片连续的内存存 储单元中,其起始地址为第一个元素a1的地址即LOC(a1),假 设每个数据元素占用k个存储单元,则任一数据元素ai的存储地 址LOC(ai)就可由以下公式求出:
可以将其压缩存放到一个一维数组b[0..n(n+1)/2-1]中,只存放 主对角和下三角部分的元素,ai,j和bk之间的映射关系:
2. 对角矩阵的压缩存储
半带宽为l的对角矩阵 :
l条
...
l条
0
对于l=1的三对角矩阵,只存储其非零元素,并存储 到一维数组b中,即以行序为主序将a的非零元素ai,j存储到 b的元素bk中,归纳起来有k=2i+j。
}
(4)将指定位臵的元素值赋给变量 对于稀疏矩阵A,执行x=A[i][j]。先在三元组表示的data 数组中找到指定的位臵,将该处的元素值赋给x,当位臵错误 时返回false。对应的算法如下:
bool SMatrixClass::GetValue(int i,int j,int &x) //执行x=A[i][j] { int k=0; if (i<0 || i>=rows || j<0 || j>=cols) return false; //下标错误时返回false while (k<nums && data[k].r<i) k++; //查找第i行的第一个非零元素 while (k<nums && data[k].r==i && data[k].c<j) k++; //在第i行中查找第j列的元素 if (data[k].r==i && data[k].c==j) //找到了这样的元素 x=data[k].d; else x=0; //在三元组中没有找到表示是零元素 return true; //取值成功时返回true }
第5章 数组和广义表
5.1 数 组
5.1.1 数组的基本概念
从逻辑结构上看,数组是一个二元组(index,value)的集合, 对每个index,都有一个value值与之对应。index称为下标,可 以由一个整数、两个整数或多个整数构成,下标含有n(n≥1) 个整数称为维数是n。数组按维数分为一维、二维和多维数组。 一维数组A是n(n>1)个相同类型数据元素a1,a2,…, an构成的有限序列,其逻辑表示为:A=(a1,a2,…,an),其中, A是数组名,ai(1≤i≤n)为数组A的第i个元素。 一个二维数组可以看作是每个数据元素都是相同类型的一 维数组的一维数组。以此类推,任何多维数组都可以看作一个 线性表,这时线性表中的每个数据元素也是一个线性表。多维 数组是线性表的推广。
(5)输出三元组 从头到尾扫描三元组表示的data数组并输出所有元素值 及其位臵。对应的算法如下:
void SMatrixClass::DispMat() //输出三元组 { int i; if (nums<=0) return; //没有非零元素时返回 cout << "\t" << rows << "\t" << cols << "\t" << nums << endl; cout << "\t------------------\n"; for (i=0;i<nums;i++) cout << "\t" << data[i].r << "\t" << data[i].c << "\t" << data[i].d << endl; }
(6)矩阵转臵 对于一个m×n的稀疏矩阵am×n,其转臵矩阵是一个n×m的 矩阵bn×m,满足bj,i=ai,j,其中0≤i≤m-1,0≤j≤n-1。用形参tb表示 转臵后稀疏矩阵对应的三元组表示。对应的算法如下:
void SMatrixClass::Transpose(SMatrixClass &tb) //矩阵转臵 { int p,q=0,v; //q为tb.data的下标 tb.rows=cols; tb.cols=rows; tb.nums=nums; if (nums!=0) //当前三元组表示中存在非零元素时执行转臵 { for (v=0;v<cols;v++) //tb.data[q]中的记录以c域的次序排列 for (p=0;p<nums;p++) //p为data的下标 if (data[p].c==v) { tb.data[q].r=data[p].c; tb.data[q].c=data[p].r; tb.data[q].d=data[p].d; q++; } } }
下三角部分 ai,j:i>j
a 0, n 1 a1, n 1 ... a 2 , n 1 ... ... ... an 1, n 1 ... ...
上三角部分 ai,j:i<j
主对角线 ai,j:i=j
1. 对称矩阵的压缩存储 若一个n阶方阵a[n,n]中的元素满足ai,j=aj,i(0≤i,j≤n-1),则 称其为n阶对称矩阵。
LOC(ai,j)=LOC(a1,1)+[(j-1)×m+(i-1)]×k
5.1.3 特殊矩阵的压缩存储
二维数组也称为矩阵,一个m行n列的矩阵,当m=n时, 称为方阵,方阵的元素可以分为三部分,即上三角部分, 主对角部分和下三角部分:
a 0 ,1 a 0, 2 a 0,0 a1, 0 a1,1 a1, 2 a 2,0 a 2 ,1 a 2, 2 ... ... ... an 1, 0 an 1,1 an 1, 2
...
0
5.2 稀疏矩阵
一个阶数较大的矩阵中的非零元素个数s相对于矩阵元
素的总个数t十分小时,即s<<t时,称该矩阵为稀疏矩阵。
5.2.1 稀疏矩阵的三元组表示