《数据结构第wu章》由会员分享,可在线阅读,更多相关《数据结构第wu章(43页珍藏版)》请在金锄头文库上搜索。
1、数据结构课程的内容1第5章 数组和广义表(Arrays A.dim=dim;A.bounds=(int *)malloc(dim * sizeof(int);if(!a.bounds) exit(OVERFLOW);/若各维长度合法,则存入A.bounds,并求出A的元素总 数elemtotalelemtotal=1;va_start(ap.dim); /ap为va_list类型,是存放变长参数表 信息的类型数组的基本操作函数说明(5个) (见教材P93-95)11for(i=0;i=0;-i)A.constantsi=A.boundsi+1*A.constantsi+1;return OK;
2、12数组基址指针各维长度保 存区指针映像函数Ci 保存区指针Status DestroyArray(Array free( A . base );A . base = NULL;if ( ! A.bounds ) return ERROR;free( A . bounds );A . bounds = NULL;if ( !A.constants ) return ERROR;free ( A. constants ) ;A. constants = NULL;return OK;13Status Locate(Array A,va_list ap,int for(i=0;iA.boundsi
3、) return OVERFLOW;off+=A.constantsi *ind;return OK;14Status Value(Array A,ElemType if(result=Locate(A,ap,off)=0) return result;e=*(A.base+off);return OK;15Status Assign(Array if(result=Locate(A,ap,off)=0) return result;*(A.base+off)=e;return OK;16顺序存储方式:按低地址优先(或高地址优先)顺序存入一维 数组。行指针向量a11a12a1nam1am2am
4、n补充: 链式存储方式:用带行指针向量的单链表来表示。注:数组的运算参见下一节实例(稀疏矩阵的转置 )(难点是多维数组与一维数组的地址映射关系)175.3 矩阵的压缩存储讨论: 1. 什么是压缩存储?若多个数据元素的值都相同,则只分配一个元素值的存储空间 ,且零元素不占存储空间。 2. 所有二维数组(矩阵)都能压缩吗?未必,要看矩阵是否具备以上压缩条件。 3. 什么样的矩阵具备以上压缩条件? 一些特殊矩阵,如:对称矩阵,对角矩阵,三角矩阵,稀疏矩 阵等。 4. 什么叫稀疏矩阵?矩阵中非零元素的个数较少(一般小于5%)重点介绍稀疏矩阵的压缩和相应的操作。18一、稀疏矩阵的压缩存储问题: 如果只存
5、储稀疏矩阵中的非零元素,那这些元素的 位置信息该如何表示?解决思路: 对每个非零元素增开若干存储单元,例如存放其所 在的行号和列号,便可准确反映该元素所在位置。实现方法: 将每个非零元素用一个三元组(i,j,aij)来表示, 则每个稀疏矩阵可用一个三元组表来表示。二、稀疏矩阵的操作19例1 : 三元素组表中的每个结点对应于稀疏矩阵的 一个非零元素,它包含有三个数据项,分别表示 该元素的 、 和 。 行下标列下标元素值例2:写出右图所示稀疏 矩阵的压缩存储形式。0 12 9 0 0 0 0 0 0 0 0 0-3 0 0 0 14 0 0 0 24 0 0 0 0 18 0 0 0 0 15 0
6、 0 -7 0 0( 1,2,12) ,(1,3,9), (3,1,-3), (3,5,14),(4,3,24), (5,2,18) ,(6,1,15), (6,4,-7)法1:用线性表表示:0 12 9 0 0 0 0 0 0 0 0 0-3 0 0 0 14 0 0 0 24 0 0 0 0 18 0 0 0 0 15 0 0 -7 0 020法2:用三元组矩阵表示 :0 12 9 0 0 0 0 0 0 0 0 0-3 0 0 0 14 0 0 0 24 0 0 0 0 18 0 0 0 0 15 0 0 -7 0 0 121213931-3351443245218611564-7注意:
7、为更可靠描述 ,通常再加一行“总 体”信息:即总行数 、总列数、非零元素 总个数668ijvalue稀疏矩阵压缩存储的缺点:将失去随机存取功能 :-(0 01 12 23 34 45 56 67 78 821法三:用带辅助向量的三元组表示 。方法: 增加2个辅助向量: 记录每行非0元素个数,用NUM(i)表 示; 记录稀疏矩阵中每行第一个非0元素在三 元组中的行号,用POS(i)表示。76531211202NUM( i)6543POS( i )21i0 12 9 0 0 0 0 0 0 0 0 0-3 0 0 0 14 0 0 0 24 0 0 0 0 18 0 0 0 0 15 0 0 -7
8、 0 0-7461516182524341453-3139311221866vji0 123456783用途:通过三元组高效访问稀疏矩阵中 任一非零元素。规律:POS(1)1POS(i)POS(i-1)+NUM(i-1)22法四:用十字链表表示 用途:方便稀疏矩阵的加减运算; 方法:每个非0元素占用5个域。right downvji同一列中下一非 零元素的指针同一行中下一非 零元素的指针 十字链表的特点: 每行非零元素链接成带表头结点的循环链表; 每列非零元素也链接成带表头结点的循环链表。 则每个非零元素既是行循环链表中的一个结点;又是列循环 链表中的一个结点,即呈十字链状。以刚才的 稀疏矩阵
9、 为例:122100H1931182523#define MAXSIZE 125000 /设非零元素最大个数125000typedef structint i; /元素行号int j; /元素列号ElemType e; /元素值 Triple; typedef structTriple dataMAXSIZE+1; /三元组表,以行为主序存入一维向量 data 中int mu; /矩阵总行数int nu; /矩阵总列数int tu; /矩阵中非零元素总个数 TsMatrix; 三元组表的顺序存储表示(见教材P98):/一个结点的结构定义/整个三元组表的定义24二、稀疏矩阵的操作 0 12 9
10、0 0 0 0 0 0 0 0 0 -3 0 0 0 14 0 0 0 24 0 0 0 0 18 0 0 0 0 15 0 0 -7 0 00 0 3 0 0 15 12 0 0 0 18 09 0 0 24 0 0 0 0 0 0 0 -7 0 0 14 0 0 0 0 0 0 0 0 0(1, 2, 12) (1, 3, 9 ) (3, 1, -3) (3, 5, 14) (4, 3, 24) (5, 2, 18) (6, 1, 15) (6, 4, -7)(1, 3, -3) (1, 6, 15) (2, 1, 12) (2, 5, 18) (3, 1, 9) (3, 4, 24) (
11、4, 6, -7) (5, 3, 14)三 元 组 表 a.data三 元 组 表 b.data转置后MT(以转置运算为例)目的:25答:肯定不正确! 除了: (1)每个元素的行下标和列下标互换(即三元组 中的i和j互换); 还应该:(2)T的总行数mu和总列数nu与M值不同(互换) ;(3)重排三元组内元素顺序,使转置后的三元组 也按行(或列)为主序有规律的排列。 上述(1)和(2)容易实现,难点在(3)。若采用三元组压缩技术存储稀疏矩阵,只要把每个 元素的行下标和列下标互换,就完成了对该矩阵的转置运 算,这种说法正确吗? 有两种实现方法压缩转置(压缩)快速转置提问:26方法1:压缩转置思路
12、:反复扫描a.data中的列序,从小到大依次进行转置 。三 元 组 表 a.data三 元 组 表 b.data(1, 3, -3)(1, 6, 15)(2, 1, 12)(2, 5, 18)(3, 1, 9)(3, 4, 24)(4, 6, -7)(5, 3, 14)(1, 2, 12) (1, 3, 9 ) (3, 1, -3) (3, 5, 14) (4, 3, 24) (5, 2, 18) (6, 1, 15) (6, 4, -7)1122col q1 2 3 4p1 2 3 427Status TransPoseSMatrix(TSMatrix M, TSMatrix T.nu=M.
13、mu; T.tu=M.tu;if (T.tu) q=1; for(col=1; col=M.nu; col+) for(p=1; p=M.tu; p+) if (M.datap.j=col)T.dataq.i=M.datap.j; T.dataq.j=M.datap.i;T.dataq.value=M.datap.value; q+;return OK; /TranposeSMatrix;压缩转置算法描述:(见教材P99)/用三元组表存放稀疏矩阵M,求M的转置矩阵T/q是转置矩阵T的结点编号 /col是扫描M三元表列序的变量 /p是M三元表中结点编号281、主要时间消耗在查找M.datap.j=col的元素,由两重循 环完成: for(col=1; col=M.nu; col+) 循环次数nufor(p=1; p=M.tu; p+) 循环次数tu 所以该算法的时间复杂度为O(nu*tu)-即M的列数与M中非零元素的个数之积最恶劣情况:M中全是非零元素,此时tu=mu*nu, 时间复杂度为 O(nu2*mu ) 注:若M中基本上是非零元素时,即使用非压缩传