设为首页 加入收藏

TOP

数据结构-数组、矩阵、广义表存储(一)
2015-07-24 10:21:22 来源: 作者: 【 】 浏览:0
Tags:数据结构 数组 矩阵 广义 存储

数组的定义

数组的定义
数组是下标index 和值value 组成的序对的集合。
在数组中,每个有定义的下标都与一个值对应,这个值称做数组元素。
每个序对形如: (index,value)

数组的顺序表示和实现

由于计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在存储器中。
一般都是采用顺序存储的方法来表示数组

一维数组的顺序表示
设第一个数组元素a[0]的存储地址是loc(a[0]),若已知每个数组元素占k个存储单元,则下标为i的数组元素a[i]的存储地址loc(a[i])为
loc(a[i])=loc(a[0])+i*k
i=0,1,2,…,n-1。

二维数组的顺序表示
二维数组a[m][n]映射到一维的存储空间时有两种顺序:行优先和列优先。
大多数语言如PASCAL、BASIC、C、C++等都是按行优先顺序存储的,FORTRAN是按列优先顺序存储的。

矩阵的压缩存储

矩阵的存储――二维数组
考虑:若矩阵阶数很高,且有许多值相同的元素或零元素,怎么提高存储效率?
特殊矩阵――值相同的元素或者零元素在矩阵中的分布有一定规律
稀疏矩阵――矩阵中有大量零元素,非零元素比较少。
压缩存储:为多个相同的非零元素只分配一个存储空间;对零元素不分配空间。

对称矩阵的压缩存储

若i?j,则aij 在下三角矩阵中。 aij 之前的i-1行(从第1行到第i-1行)一共有1+2+…+i-1=i(i-1)/2个元素,在第i行上, aij 之前恰有j-1个元素(即ai0,ai1,ai2,…,aij-1),因此有:
               k=i*(i-1)/2+j-1                 当 i?j
 若i

三角矩阵的压缩存储

三角矩阵中的重复元素c可共享一个存储空间,其余的元素正好有n(n+1)/2个,因此,三角矩阵可压缩存储到一维数组sa[n(n+1)/2+1]中,其中c存放在数组的第1个位置(亦可放在最后一个位置)。
上三角矩阵元素aij保存在数组sa中时,下标值k与(i,j)之间的对应关系是?
下三角矩阵元素aij保存在数组sa中时,下标值k与(i,j)之间的对应关系是?

稀疏矩阵的存储

解决方法:在存储非零元素的同时,同时记下它所在的行和列的位置(i, j)。
由于三元组(i, j, aij)唯一确定了矩阵A的一个非零元。因此,稀疏矩阵可由表示非零元的三元组及其行列数唯一确定。
例如,下列三元组表
( (1,2,12), (1,3,9), (3,1,-3), (3,8,4), (4,3,24), (4,6,2), (5,2,18), (6,7,-7), (7,4,-6) ) 和行列信息(7,8,9)便可描述如图5.6所示的稀疏矩阵
注:行列信息(7,8,9)中,7:行;8:列;9:非零元个数

三元组顺序表

以顺序存储结构来表示三元组表,则得到稀疏矩阵的一种压缩存储方法――三元顺序表。

⑴ 三元组结点定义    
  #define MAX_SIZE 1000
  typedef int elemtype ;
  typedef struct
{    int   row ;     /*  行下标  */
      int   col ;        /*  列下标  */
elemtype value;      /*  元素值  */
}Triple ;
⑵  三元组顺序表定义    
typedef struct 
{   int  rn ;         /*   行数   */
int  cn;         /*   列数   */
int  tn ;         /*    非0元素个数   */
Triple   data[MAX_SIZE] ; 
}TMatrix ; 
TMatrix  a;//定义了一个用三元组顺序表表示的稀疏矩阵

矩阵的转置

设稀疏矩阵A是按行优先顺序压缩存储在三元组表a.data中,若仅仅是简单地交换a.data中i和j的内容,得到三元组表b.data,b.data将是一个按列优先顺序存储的稀疏矩阵B,要得到按行优先顺序存储的b.data,就必须重新排列三元组表b.data中元素的顺序。
由于A的列是B的行,因此,按a.data的列序转置,所得到的转置矩阵B的三元组表b.data必定是按行优先存放的。

转置矩阵的算法

按方法一求转置矩阵的算法如下:
void TransMatrix(TMatrix a , TMatrix * b)
{   int i , j , col ;
b->rn=a.cn ; b->cn=a.rn ; b->tn=a.tn ;
/*    置三元组表b->data的行、列数和非0元素个数 */
if  (b->tn==0)    printf(“ The Matrix A=0\n” );
else{   j=0; //b中三元组 数组下标
for  (col=1; col<=a.cn ; col++)
/*   每次循环扫描 a的第col 列非零元,得到b的第col行非零元  */
      for  (i=0 ;i data[j].row=a.data[i].col ;
                                         b-> data[j].col=a.data[i].row ; 
                                         b-> data[j].value=a.data[i].value; 
                                         j++ ;
                                     }
                    }  }

快速转置算法

快速转置算法如下
   void  FastTransMatrix(TMatrix a, TMatrix b)
{    int p , q , col , k ;
int num[N] , copt[N] ;  //N为矩阵列数
b.rn=a.cn ; b.cn=a.rn ; b.tn=a.tn ;
 /*   置三元组表b.data的行、列数和非0元素个数  */ 
if  (b.tn==0)    printf(“ The Matrix A=0\n” ) ;
else
{  for (col=1 ; col<=a.cn ; ++col)    num[col]=0 ;
   /*  向量num[ ]初始化为0   */
               for (k=0 ; k

十字链表(链式存储)

    对于稀疏矩阵,当非0元素的个数和位置在操作过程中变化较大时,采用链式存储结构表示比三元组的线性表更方便。
   矩阵中非0元素的结点所含的域有:行、列、值、行指针(指向同一行的下一个非0元)、列指针(指向同一列的下一个非0元)。其次,十字交叉链表还有一个头结点

稀疏矩阵中同一行的非0元素的由right指针域 链接成一个行链表, 由down指针域链接成一个列链表。
每个非0元素既是某个行链表中的一个结点,同时又是某个列链表中的一个结点,所有的非0元素构成一个十字交叉的链表,称为十字链表。

此外,用两个一维数组rhead和chead分别存储行链表的头指针和列链表的头指针。
结点的描述如下:
typedef struct  OLnode  
{   int  row , col ;   /*  行号和列号  */     
elemtype value ;    /*  元素值  */
struct  OLnode  *down , *right ;
} OLNode, *OLink ;   /*  非0元素结点  */

typedef struct
{   int   rn;        /*  矩阵的行数  */     
int   cn;        /*  矩阵的列数  */
int   tn;        /*  非0元素总数  */
OLink  * rhead ;      //行链表头指针向量基址
OLink  * chead ;    //列链表头指针向量基址
} CrossList 

广义表

广义表是线性表的推广和扩充,在人工智能领域中应用十分广泛。
第2章中的线性表定义为n(n?0 )个元素a1, a2 ,…, an的有穷序列,该序列中的所有元素具有相同的数据类型且只能是原子项(Atom)。所谓原子项可以是一个数或一个结构,在结构上不可再分。若放松对元素的这种限制,容许它们具有其自身结构,就产生了广义表的概念。
广义表(Lists,又称为列表 ):是由n(n ?0)个元素组成的有穷序列: LS=(a1,a2,…,an) ,其中ai或者是原子项,或者是一个广义表。LS是广义表的名字,n为它的长度。若ai是广义表,则称为LS的子表。
习惯上:原子项用小写字母,子表用大写字母。
若广义表LS非空时:
◆ a1(表中第一个元素)称为表头

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇小玩意:如何克隆一份记录及其子.. 下一篇数据结构-静态查找

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C 内存管理 | 菜鸟教 (2025-12-26 20:20:37)
·如何在 C 语言函数中 (2025-12-26 20:20:34)
·国际音标 [ç] (2025-12-26 20:20:31)
·微服务 Spring Boot (2025-12-26 18:20:10)
·如何调整 Redis 内存 (2025-12-26 18:20:07)