c++数据结构 浅谈广义表与矩阵

广义表

参考书籍:c++数据结构、数据结构第二版

谈到数组我们肯定都不会陌生,本次我们要以抽象数据的形式讨论数组的定义和实现。我们可以把二维数组看成是一个定长的线性表;它的每个数据元素也是一个定长线性表。在C语言中,一个二维数组类型定义为其分量类型为一维数组类型的一维数组类型,也就是说,
typedef ElemType Array2[m][n];
等价于:
typedef ElemType Array1[n];
typedef Array1 Array2[m];
数组一旦被定义,它的维度和维界就不再改变。因此,除了结构的初始化和销毁之外,数组只有存取元素和修改元素的值

数组的顺序表示和实现

对二维数组可以有两种表达方式:一种是以行序为主序的存储方式(大部分语言都是这么存储的)另一种是以列序为主序的存储结构。
对于数组,一旦规定了它的维度和各维的长度,便可为它分配存储空间。反之,只要给出一组下标便可求得相应数组元素的存储位置。
假设每个数据元素占L个单元,则二维数组A中任意一个元素aij的存储位置可由下式确定:
LOC(i,j) = LOC(0,0) + (b2Xi + j)L;
LOC(i,j)是aij的存储位置;LOC(0,0)是a00的存储位置,即基址;b2则为给数组第2维的长度。
由于计算各个元素存储位置的时间相同,所以存取数组中任一元素的时间也就相等。我们称具有这一特点的存储结构为随机存储结构
由于广义表中的元素可以是不同类型的,既可以是原子,也可以是广义表,而且长度也很不固定,很难用顺序的数据结构来表,所以通常用链式的数据结构来表示。
又因为表种的元素可能是原子,也有可能是另一个广义表,该结点必须能够同时存储这两种类型的数据,为此,可以在该结点中用一个标志域来标识存放的是原子还是广义表(此方法类似队列中判断是否队满)。由此,表结点可由3个域组成:标志域、指向表头的指针、指向表尾的指针。而原子结点只存在两个域:标志域和值域。
下面是数组的顺序存储表示:


typedef enum{ATOM,LIST} ElemTag;    /*ATOM表示原子,即广义表中的最小成员,enum为枚举函数,其中 
            ATOM = 0,LIST = 1*/
typedef char AtomType;
struct GLNode{
 ElemTag atom;
 union{          /*union与struct类似,具体区别为1.union的成员会共同占用一块内存
                    struct的成员会各自占用不同的内存 
                      2.union中修改一个成员会影响其他成员*/ 
  AtomType atom;		//原子数据
  struct{
   struct GLNode *hp,*tp;		//广义表指针,ptr.hp和ptr.tp为表头和表尾指针
  }ptr; 
 };val; 
}GLNODE,*GList;

矩阵的压缩存储

通常,用高级语言编制程序时,都是用二维数组来存储矩阵元。然而,在数值分析中经常出现一些阶数很高的矩阵,同时在矩阵中有许多相同的元素或者零元素。有时为了节省存储空间,可以对这类矩阵进行压缩存储。所谓压缩存储是指:为多个值相同的元素只分配一个存储空间;对零元不分配空间
假若值相同的元素或者零元素在矩阵中的分布有一定规律,则我们称此类矩阵为特殊矩阵;反之,称为稀疏矩阵

一、特殊矩阵
若n阶矩阵A中满足下述性质aij = aji
则称为n阶对称矩阵。对于对称矩阵,我们可以为每一对对称元分配一个存储空间,则可将n方个元压缩存储到n(n+1)/2个元的空间中。不失一般性,我们可以行序为主序存储其下三角(包括对角线)中的元。
这种压缩存储的方法同样也适用于三角矩阵。
在数值分析中经常出现的还有另一类特殊矩阵是对角矩阵,在这种矩阵中,所有的非零元都集中在以主对角线为中心的带状区域中。即除了主对角线上和直接在对角线上、下方若干条对角线上的元之外,所有其他的元皆为零。
在所有这些我们统称为特殊矩阵的矩阵中,非零元的分布都有一个明显的规律,从而我们都可将其压缩存储到一维数组中,并找到每个非零元在一维数组中的对应关系。
然而,在实际应用中我们还会经常遇到另一类矩阵,其非零元较零元少,且分布没有一定规律,我们称之为稀疏矩阵

二、稀疏矩阵
如何进行稀疏矩阵的压缩存储呢?
按照压缩矩阵的概念,只存储稀疏矩阵的非零元。因此,除了存储非零元的值之外,还必须同时记下它所在的行和列的位置(i,j)。反之,一个三元组(i,j,aij)惟一确定了矩阵A的一个非零元。由此,稀疏矩阵可由表示非零元的三元组及其行列数唯一确定。
三元组顺序表
假设以顺序存储结构来表示三元组表,则可得稀疏矩阵得一种压缩存储方式----我们称之为三元组顺序表
代码实现:

#define MAXSIZE 12500		//假设非零元个数的最大值为12500
typedef struct {
	int i, j;				//该非零元的行下表和列下标
	int e;
}Triple;
typedef struct {
	Triple data[MAXSIZE + 1];
	int mu, nu, tu;
}TSMatrix;

你可能感兴趣的:(数据结构,c++数据结构,矩阵与广义表)