数组和广义表

在原线性结构中,当数据元素本身也是一个数据结构时,多层嵌套递归定义便有了 (多维)数组广义表.

一.数组

(一)知识点

  • 数组定义:
    以二维数组举例
typedef ElemType Array2[m][n];

等价于

typedef ElemType Array1[n];
typedef Array1 Array2[m];

可见其嵌套的定义结构。

  • 数组一旦被定义,它的维数以及维界便不再改变。因而除了结构的初始化和销毁,只有取元素和修改元素的操作。

  • 数组仍是特殊的线性表

(二)数组的顺序表示和实现

2.1 知识点

  • 对二维数组有两种存储方式:行序为主序或以列序为主序(常见,仅就此做讨论)。
  • 每个数据元素占L个存储的单元,则二维数组 A ( m , n ) A(m,n) A(m,n) a i j a_{ij} aij的存储位置:
    L O C ( i , j ) = L O C ( 0 , 0 ) + L ( n × i + j ) LOC(i,j)=LOC(0,0)+L(n\times{i}+j) LOC(i,j)=LOC(0,0)+L(n×i+j)
  • 对于n维数组, a j 1 j 2 … … j n a_{j1j2……jn} aj1j2jn,各维的长度b1、b2、……、bn。则其存储位置:
    L O C ( j 1 , j 2 , … … , j n ) = L O C ( 0 , … … , 0 ) + L ( j 1 × b 2 × b 3 × … … × b n + j 2 × b 3 × b 4 × … … × b n + … … + j n ) LOC(j_1,j_2,……,j_n)=LOC(0,……,0)+L(j_1\times{b2\times{b3}\times{……\times{bn}}}+j_2\times{b3\times{b4}\times{……}\times{bn}}+……+j_n) LOC(j1,j2,jn)=LOC(0,0)+L(j1×b2×b3××bn+j2×b3×b4××bn++jn)
    即:
    L O C ( j 1 , j 2 , … … , j n ) = L O C ( 0 , … … , 0 ) + ∑ i = 1 n c i j i , 其 中 c n = L , c i − 1 = b i × c i , 1 < i ≤ n LOC(j_1,j_2,……,j_n)=LOC(0,……,0)+\sum_{i=1}^{n}c_ij_i ,其中c_n=L,c_{i-1}=b{i}\times{c_i},1<i\le{n} LOC(j1,j2,jn)=LOC(0,0)+i=1nciji,cn=L,ci1=bi×ci,1<in
  • 存取数组中任一元素的时间相等,称其为随机存储结构
  • 多维数组的地址运算。
    如PASCAL中,有A(-2,8)[A[-2],A[8]]闭区间。

(三)矩阵的压缩处理

3.1知识点

  • 压缩处理:为多个值相同的元只分配一个存储空间;对零元不分配空间。
  • 若值相同的元素或者零元素在矩阵中的分布有一定的规律,则为特殊矩阵,反之为稀疏矩阵

3.2 特殊矩阵

  • 对称阵
    • 满足 a i j = a j i , 1 ≤ i , j ≤ n a_{ij}=a_{ji},1\le{i,j}\le{n} aij=aji,1i,jn
    • 将n2个元存储到n(n+1)/2个元当中,以行序为主序存储其下三角中的元为例
    • 设一维数组s[ n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1)]作为n阶对称矩阵A的存储结构,则s[k]和 a i j a_{ij} aij的对应关系:
      k = { i ( i − 1 ) 2 + j − 1 , i ≥ j , ( 下 三 角 ) j ( j − 1 ) 2 + i − 1 , j < i , ( 上 三 角 ) , k = 0 , 1 , … … , n ( n + 1 ) 2 − 1 k=\begin{cases} \frac{i(i-1)}{2}+j-1,& {i\ge{j,(下三角)}}\\\frac{j(j-1)}{2}+i-1,& {j<i,(上三角)} \end{cases} ,k=0,1,……,\frac{n(n+1)}{2}-1 k={2i(i1)+j1,2j(j1)+i1,ij,()j<i,(),k=0,1,2n(n+1)1
      则s[k]为A的压缩存储。
  • 三角阵
    • 与对称阵类似的存储方式,但不包括对角线中的元。
    • 若矩阵的上三角/下三角中的元均为常数c,则外加一个存储常数c的空间即可。
      s[k]与 a i j a_{ij} aij的对应关系:
      k = { ( i − 1 ) ( i − 2 ) 2 + j − 1 , i ≥ j 且 i ≥ 2 ( 下 三 角 ) ( j − 1 ) ( j − 2 ) 2 + i − 1 , i < j 且 j ≥ 2 ( 上 三 角 ) k = 0 , 1 , … … , n ( n − 1 ) 2 − 1 k=\begin{cases} \frac{(i-1)(i-2)}{2}+j-1,& i \ge{j}且i\ge2(下三角)\\\frac{(j-1)(j-2)}{2}+i-1,& i<j且j\ge2(上三角)\end{cases} k=0,1,……,\frac{n(n-1)}{2}-1 k={2(i1)(i2)+j1,2(j1)(j2)+i1,iji2i<jj2k=0,1,2n(n1)1
  • 带状(对角)矩阵
    • 所有非零元素都对称集中在主对角线附近,其它元皆为0;
    • 带宽S:即主对角线一侧(不包括主对角线)的对角线条数。
    • 则除第一行有S+1个元素外,其他一行有2S+1个元素。(非零端补齐)
    • 则s[k]与 a i j a_{ij} aij的对应关系为:
      k = ( 2 S + 1 ) ( i − 1 ) + j − i k=(2S+1)(i-1)+j-i k=(2S+1)(i1)+ji

3.3 稀疏矩阵

  • 定义

    • 稀疏因子 δ = t m + n ≤ 0.05 \delta=\frac{t}{m+n} \le0.05 δ=m+nt0.05 (在m*n矩阵中有t个元素不为零其它全为0)
  • ADT定义

      1. CreateSMatrix(&M);
      2. DestroySMatrix(&M);
      3. PrintSMatrix(M);
      4. CopySMatrix(M,&T);
      5. AddSMatrix(M,N,&Q);	//稀疏矩阵M和N的和Q
      6. SubSMatrix(M,N,&Q);//差
      7. MultSMatrix(M,N,&Q);
      8.TransposeSMatrix(M,&T);//求转置 
    
  • 压缩存储

    • 只由三元组(i,j, a i j a_{ij} aij)表示稀疏矩阵中的一个非零元。
    • 由三元组的不同表示方法有不同的压缩存储方法

3.3.1 三元组顺序表

  • 存储结构(行主序)
#define MAXSIZE 12500		//非零元的最大个数
typedef struct{
	int i,j;	//该零元行下标、列下标
	ElemType e;
}Triple;
typedef struct{
	Triple data[MAXSIZE+1];//data[0]未用
	int	mu,nu,tu;	//矩阵的行数、列数和非零元的个数
}TSMatrix;
  • 求转置矩阵的算法
    • 暴力双循环迭代

      最容易想到的——双层循环转置不多说。时间复杂度为O(mu*tu)

    • 快速转置法

        1. 首先扫描一遍,另附num向量对应nu,记录原矩阵每一列的非零元素的个数;(tu)
        2. 再次扫描一遍,另设cpot向量为原矩阵每一列元素的第一个对应于转置矩阵的三元组顺序表中的行数。(前num的和+1,第一个为1)(nu)
        3. 顺序原三元组表,均可以知道当前元素再转置后的三元组表中的位置是第几行。按着头给它放上去就行。(tu)
      

      时间复杂度:O(nu+tu);空间复杂度O(nu)


3.3.2 行逻辑链接的顺序表

  • 阿巴阿巴阿巴叭叭叭baba

3.3.3 十字链表

  • 连接式存储
    多维数组(稀疏矩阵)宜用连接式存储
    结点Node:
struct Node(
			struct Node *left,up;
			int row,col;
			ValueType val;
			};
  • 需要BaseCao[i],BaseRow[i]作为循环链表指向链尾(表尾)

广义表

特征

  • 线性表的推广结构,可以取不同类型:原子,广义表……

  • 如:
    A = (a,b,(s,d),A,(((2))))
    非线性

  • 表头:非空广义表的第一个元素

  • 表尾:除第一个元素外的其余元素组成的广义表
    ->广义表的表尾一定是广义表
    ->((a,b),a,b)的表头和表尾相等。

存储结构

struct listnode{
	struct listnode *link;
	boolean tag;//原子为false,广义表为true
	union{
		char data;
		struct listnode *dlink;
		};
	};
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值