数据结构(矩阵和广义表)

目录

一、矩阵

5.1.1 矩阵的基础知识

1.矩阵的存储结构

(1)含义

(2)图示

(3)利用一维数组来顺序存储矩阵 

1)行优先顺序存储

2)列优先存储

2.特殊矩阵的压缩存储

(1)特殊矩阵的含义

(2)压缩存储

1)对称矩阵的压缩存储

 2)三角矩阵的压缩存储

 3)对角矩阵的压缩存储

 3.稀疏矩阵的压缩存储

二、广义表

 5.2.1 广义表的基础知识

1.广义表的概念

(1)含义

(2)特点

 2.广义表中结点结构

1)原子

2)子广义表

 3.广义表的存储结构

三、总结 


一、矩阵

5.1.1 矩阵的基础知识

1.矩阵的存储结构

(1)含义

在实际应用中,数值以表的形式出现,该表就被称为矩阵。由m*n个数值Aij排列成的m行n列的表。

(2)图示

注:实际应用中,矩阵的下标从1开始,但c语言以及c++中此表从0开始

(3)利用一维数组来顺序存储矩阵 
1)行优先顺序存储

a.将矩阵的元素按照行排列顺序的存储在一维数组中,即第i+1个元素存放在第i个元素后面。行优先存储适用于下三角矩阵以及对称矩阵。

b.以行优先顺序存储后元素的地址a_{ij}a_{ij}a_{ij}可以通过公式来查找: 

LOC(a_{ij})=LOC(a_{11})+((i-1)*n+j-1)*d

注:LOC(a_{ij})表示元素a_{ij}的存储地址,d表示每个元素在内存中占用的单元数 

2)列优先存储

将矩阵的元素按照列排列顺序的存储在一维数组中,即第j+1个元素存放在第j个元素后面。列优先存储常适用于上三角矩阵。

2.特殊矩阵的压缩存储

(1)特殊矩阵的含义

矩阵中零元素或值相同的非零元素分布具有一定的规律,称为特殊矩阵,包含对称矩阵,三角矩阵,对角矩阵。

(2)压缩存储
1)对称矩阵的压缩存储

1.对角线满足a_{ij}=a_{ji},1\leq i,j\leq n称为对称矩阵

2.存储

当我们压缩存储对称矩阵时,只需要存储矩阵的上三角或者下三角即可,目的是节省存储空间。

n阶矩阵的三角部分的元素公有\tfrac{n*(n=1)}{2}个元素。即需要\tfrac{n*(n=1)}{2}个存储空间。

随机访问数组中的元素是,位于a_{ij}前面的公有i-1行元素,其前面还有j-1个元素。当i<j是表名该元素是位于上三角的。则a_{ij}与一维数组sad[k]的关系是:K=\begin{cases} & \text{ } i*(i-1)/2+j-1,i\geq j \\ & \text{ } j*(j-1)/2+i-1,i< j \end{cases}

3.图示

a.下三角

b.上三角

 2)三角矩阵的压缩存储

1.三角矩阵指的是上三角和下三角矩阵,上三角时起左下角的数均为常数c,下三角同理。

2. 存储

存储三角矩阵时只需要按行顺序存储下三角或下三角中的元素和一个常数c即可。

对于下三角一维数组sad[k]a_{ij}的关系如下 :

K=\begin{cases} & \text{}i(i-1)/2+j+1,j\geq i\\ & \text{ }n(n+1)/2,i<j \end{cases}

对于上三角一维数组sad[k]a_{ij}的关系如下:

K=\begin{cases} & \text{} (i-1)*(2n-i+2)/2+j-i,i\leq j\\ & \text{} n*(n+1)/2,i>j \end{cases}

3.图示

a.上三角

b.下三角

 3)对角矩阵的压缩存储

1.对角矩阵即处理主对角线和主对角线相邻两侧的若干条对角线上的元素之外其余元素皆为零

2.存储

将主对角线和主对角线相邻两侧的若干条对角线上的元素按照行优先或列优先的顺序存储到一位数组中。

sad[k]a_{ij}关系如下:k=2*i+j-3

3.图示

 3.稀疏矩阵的压缩存储

(1)含义

稀疏矩阵即矩阵中95%的元素等于0,由于稀疏矩阵的非零元素的存储没有逻辑可循,因此存储时矩阵中的一个非零元素a_{ij}需要由一个三元组(i,j,a_{ij})唯一确定

(2)三元线性表的存储方式

1.三元线性表的存储可分为顺序和链式存储,分别对应三元组顺序表和十字链表

2.三元组顺序表

举例图示:左侧是需要进行压缩存储的矩阵,右侧是其对应的三元组顺序表。

注:a.其中i表示非零元素在多少行,j表示非零元素在多少列,e表示非零元素本身

b.优点:非零元素在表中按行序有序存储,便于进行依行顺序处理的矩阵运算

c.缺点:不能随机存取,若按行号存取其中某行中的非零元素,则需要从头开始。 

 3.十字链表

五域组成

十字链表即稀疏矩阵中同一行的非零元素通过向右指针right指针域按列号顺序连接成一个线性链表,同一列的非零元素通过向下指针down指针域按行号顺序连接成一个线性表,使得每个非零元素即是行链表中的一个结点,同时又是列链表的结点。

举例图示:

 注:优点:可随机存取,操作灵活

缺点:繁琐

4.稀疏矩阵的拓展(简述)

(1)朴素转置

将需要存储在三元组中的矩阵元素的行列进行转置交换(转置即将矩阵的行转化为列,列转化为行,此部分基础薄弱的需要先去补习线性代数矩阵的知识)

举例图示:左侧是稀疏矩阵,中间是三元组顺序表,右侧是转置后的矩阵存储的三元组顺序表

 (2)快速转置

二、广义表

 5.2.1 广义表的基础知识

1.广义表的概念

(1)含义

广义表是n(n\geq 0)个数据元素组成的有限序列,记作:GList = (a_{1},a_{2},....,a_{n}) 

其中a_{i}既可以是单个数据元素称为原子,也可以是广义表称为子表

n=0是为空表

(2)特点

1)表头:广义表的表头指的是广义表第一个元素,可以是原子也可以是广义表

表尾:广义表的表尾指的是除去表头以外的其余元素都是表尾。

 2)广义表的数据元素有相对次序(是顺序的),广义表中的元素都有一个直接前驱和一个直接后继。

 3)广义表的长度:最外层所包含的元素个数

4)广义表的深度:广义表展开后所含括号的层数

注:原子的深度为0,空表深度为1

5)广义表的共享:A=(),B=(()),B=(())==B=(A)即包含关系 

 6)广义表的递归:F=(a,F)=(a_{},(a,(a,.....)))

注:广义表的递归表深度为无穷值,长度是有限的

7)广义表的多层次结构:即广义表中的元素可与是单元素,也可以是子表,子表中的元素还可以是子表。

 2.广义表中结点结构

1)原子

2)子广义表

其中type的值ATOM常以0表示 

 3.广义表的存储结构

1)广义表的存储中,每个子表结点相当于子表的“头结点”,即每个子表是带头结点的链表

 2)举例图示:存储广义表(a,b,c)

上述例子中a即为广义表的表头

3)广义表的操作

创建广义表

//引入原子组成结构体

enum GListNodeType{ATOM,LIST};

typedef char ElemType;
typedef struct GListNode {
    GListNodeType type;
    union {
        ElemType data;
        GListNode* sublist;
    };
    GListNode* next;

}GListNode, * GList;

GList CreateGList(char*& s) {
    GListNode* p;
    while (*s == ' ' || *s == ',')
        s++;
    char e = *s;
    s++;
    if (e == '(') {
        p = new GListNode;
        p->type = LIST;
        p->sublist = CreateGList(s);
        p->next = CreateGList(s);
        return p;
    }
    if (e == ')' || e == '\0')
        return NULL;
    p = new GListNode;
    p->type = ATOM;
    p->data = e;
    p->next = CreateGList(s);
    return p;
}

计算广义表的长度

 int length(GList gl) {
    GListNode* p;
    int n = 0;
    p = gl->sublist;
    while (p) {
        p = p->next;
        n++;
    }
    return n;
}

 计算广义表的深度

int Depth(GList gl) {
    GListNode* q;
    int maxdepth = 0, depth;
    if (gl->type == ATOM) {
        return 0;
    }
    q = gl->sublist;
    while (q) {
        depth = Depth(q);
        if (depth > maxdepth) maxdepth = depth;
        q = q->next;

    }
    return maxdepth + 1;
}

 销毁广义表

void DestroyGList(GList& p) {
    GListNode* q;
    if (p == NULL) {
        return;
    }
    q = p;
    p = p->sublist;
    delete q;
    while (p) {
        q = p;
        p = p->next;
        if (q->type == ATOM) {
            delete q;
        }
        else {
            DestroyGList(q);
        }
    }
}

三、总结 

1.以上便是有关矩阵和广义表的大致内容了,其中我们需要注意并且要求掌握的是对称矩阵,三角矩阵以及对角矩阵求矩阵中任意元素的位置方法是:我们需要查找某元素在其中的位置即要知道该元素前面有多少个元素,以及后面有多个元素,将总的元素个数减去其前面的元素个数,或者后面的元素个数即可得到该位置,详细的公式对应查看各矩阵的压缩存储

2.广义表中其7条特征我们是需要记住的,有关广义表的题目大多数都是和这起跳特征是挂钩的,掌握了这七条特征应对此类题目并不是什么难事。代码部分需要长时间磨合,短期内感到困难不要紧。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值