数据结构与算法(C/C++版)【数组】
第五章《数组》
一、概念
根据数组中存储的数据元素之间的逻辑关系,可以将数组分为 : 一维数组、二维数组、…、n维数组。
n维数组中,维数 n 的判断依据是:根据数组中为确定元素所在位置使用的最少的下标个数。例如,二维数组中想唯一确定一个元素的位置,至少需要使用 2 个下标, a[1][1]:行坐标为 1,列坐标为 1 的数据元素的值。
二、数组VS顺序表
①数组作为一种数据类型,作用是将类型相同的数据存储在一整块内存中,数组中存储的数据之间没有任何逻辑关系,谁也不认识谁。
②顺序表作为线性表的存储结构,存储的这些数据元素在物理存储结构上相邻的同时,在逻辑结构上也相邻,每个数据元素都清楚地知道紧挨着它的前边的元素和后边的元素。
简要概述:用数组来存储的线性表是顺序表。
三、数组的逻辑结构
数组它可以看作线性表的推广。数组作为一种数据结构其特点是结构中的元素本身可以是具有某种结构的数据,但属于同一数据类型,比如:一维数组可以看作一个线性表,二维数组可以看作“数据元素是一维数组”的一维数组,三维数组可以看作“数据元素是二维数组”的一维数组,依此类推。所以,n 维数组可以看作是线性表的一种扩展。


数组是一个具有固定格式和数量的数据有序集,每一个数据元素有唯一的一组下标来标识,因此,在数组上不能做插入、删除数据元素的操作。通常在各种高级语言中数组一旦被定义,每一维的大小及上下界都不能改变。在数组中通常做下面两种操作:
(1)取值操作:给定一组下标,读其对应的数据元素。
(2)赋值操作:给定一组下标,存储或修改与其相对应的数据元素。
我们着重研究二维和三维数组,因为它们的应用是广泛的,尤其是二维数组。
四、数组的存储
按元素的下标求m×n二维数组中某个数据元素 aij地址的计算:
①行优先:LOC(aij) = LOC(a00) + ( i*n + j ) * s
②列优先:LOC(aij) = LOC(a00) + ( i*m + j ) * s
其中,LOC(i,j) : aij 在内存中的地址;LOC(0,0) : a00 存储的地址,其实就是整个二维数组存放的起始地址。
【例】设二维数组A[][],每个数组元素占4个存储单元,若按行优先顺序存放的数组元素A[][]的存储地址是1000,求A[][]的存储地址。
解: = X + (*+)* 解的:X=
五、特殊矩阵的压缩存储
如果矩阵中有很多数值相同的数据元素,在存储时,可以考虑对其进行适当的压缩存储。
有必要压缩存储的矩阵大致分为两大类:
①矩阵中含有大量的相同数值,称为特殊矩阵(例如对称矩阵和上下三角矩阵)。
②矩阵中只有极少量的元素是非 0 元素,称为稀疏矩阵。
两类矩阵压缩存储的方法:
①特殊矩阵中,对于相同的数据元素,只存储一个。
②稀疏矩阵中,只需要存储非 0 元素。
(1)对称矩阵
定义:n阶矩阵中的元素满足: aij = aji ( i 为行标, j 为列标)
图为 3 阶对称矩阵,图中的虚线为矩阵的 “主对角线” ,主对角线上方区域称为 “上三角” ;主对角线下方称为 “下三角” ,沿主对角线对称的数据元素一一相等,所以对于此矩阵来说,只需要存储 6 个元素即可(1,2,3,4,5,6)。
原来需要n*n个存储单元,现在只需要n(n+1)/2个存储单元了,节约了n(n-1)/2个存储单元,当n较大时,这是可观的一部分存储资源。
若将对称矩阵压缩存储在一维数组 S[k] 中,矩阵中数据元素在数组中存储的位置和所在的行标(用 i 表示)和列标(用 j 表示)有关。
对称矩阵沿主对角线对称的数据元素相等,任选一边的数据元素进行存储即可:
①存储下三角区域的数据元素:

②存储上三角区域的数据元素:

综上所述,对于对称矩阵中的任意元素aij,若令I=max(i,j),J=min(i,j),则将上面两个式子综合起来得到: k=I*(I-1)/2+J-1

(2)上下三角矩阵
定义:上下三角矩阵,和对称矩阵类似,不同在于,上三角矩阵是指主对角线下方的元素(不包括主对角线上的)都是常数C(包括数值 0 );同理,下三角矩阵是指主对角线上方的元素都是常数C。

存储时,上(下)三角存储上(下)三角的数据元素,除此之外,额外存储一个下(上)三角含有的常数C(图中,C==0)
(3)对角矩阵
定义:除了主对角线和它的上下方若干条对角线的元素外,所有其他元素都为零(或同一个常数c)


(4)稀疏矩阵
定义:矩阵中只含有少量的非 0 元素,相比于使用普通方式将矩阵中的所有数据元素一一存储,只存储非 0 元素更节省内存空间。

矩阵压缩存储的方式有 3 种,分别为:①三元组顺序表、②行逻辑链接的顺序表、③十字链表
①三元组顺序表
定义:除了要存储非 0 元素的值之外,还需要存储元素所在矩阵中的行标 i 和列标 j ,三个元素构成三元组(行标,列标,元素值)
结构体:
//三元组结构体
typedef struct {
int i,j;//行标i,列标j
int data;//元素值
}triple;
每个稀疏矩阵的表示,需要存储矩阵中所有非 0 元素的三元组,并且还需要记录矩阵的行数和列数,这样才能唯一确定一个稀疏矩阵。
矩阵的结构也需要使用结构体实现:
#define number 100
//矩阵的结构表示
typedef struct {
triple data[number];//存储该矩阵中所有非0元素的三元组
int n,m,num;//n和m分别记录矩阵的行数和列数,num记录矩阵中所有的非0元素的个数
}TSMatrix; //例如,对于图 3 的稀疏矩阵来说,即将(2,2,3)、(2,3,4)、(3,2,5)存储进 data 数组,并且存储稀疏矩阵的行数 3 和列数 3 ,该稀疏矩阵中非 0 元素有 3 个。

②行逻辑链接的顺序表
使用三元组顺序表存储矩阵后,当需要提取矩阵某一行的非 0 元素时,需要遍历整个顺序表。
为了提高查找的效率,在三元组顺序表的基础上,增加一个数组用于记录每一行第一个非 0 元素的存储位置,这样的存储结构,称为:行逻辑链接的顺序表。
#define number 100
typedef struct {
int i,j;
int data;
}triple;
typedef struct {
triple data[number];
int rpos[number];//存储各行第一个非0元素在三元组表中的位置
int n,m,num;
}TSMatrix;
③十字链表
以上两种存储稀疏矩阵的方法,说到底,还是操作数组,在进行矩阵运算过程中,如果有插入非 0 元素或者删除某一个元素的操作,可能需要大量的移动数组中的三元组。
例如在进行“将矩阵 B 加到矩阵 A 上”的操作时,矩阵 A 中的数据元素会发生很大的变化,之前的 0 元素可能变成非 0 元素,非 0 元素也可能变成 0 (正负数相加为 0)。在这种情况下,就需要使用链表的存储结构来存储矩阵,这种存储方式称为:十字链表法。
例如,将下列矩阵以十字链表的方式存储起来:

采用十字链表法存储矩阵的非 0 元素时,链表中的结点由 5 部分组成:

两个指针域:一个指向所在列的下一个元素,一个指向所在行的下一个元素。
typedef struct OLNode{
int i,j;
int data;
struct OLNode * right,*down;
}OLNode;
//此结构体表示一个矩阵,其中包含矩阵的行数,列数,非0元素的个数以及用于存储各行以及各列元素头指针的动态数组rhead和chead。
typedef struct {
OLNode * rhead,*chead;
int n,m,num;
}CrossList;
总结:
稀疏矩阵的三种不同的存储方法,采用哪种方法要看程序具体要实现的功能:
--如果想完成例如矩阵的转置这样的操作,宜采用三元组顺序表;
--如果想实现矩阵的乘法这样的功能,宜采用行逻辑链接的顺序表;
--如果矩阵运算过程中(例如矩阵的加法),需要不断地插入非 0 元素或删除变为 0 的元素,宜采用十字链表法。
数据结构与算法(C/C++版)【数组】的更多相关文章
- 重读《学习JavaScript数据结构与算法-第三版》- 第4章 栈
定场诗 金山竹影几千秋,云索高飞水自流: 万里长江飘玉带,一轮银月滚金球. 远自湖北三千里,近到江南十六州: 美景一时观不透,天缘有分画中游. 前言 本章是重读<学习JavaScript数据结构 ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第5章 队列
定场诗 马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁! 前言 本章为重读<学习JavaScript数据结构与算法-第三版>的系列文章,主要讲述队列数据 ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第3章 数组(一)
定场诗 大将生来胆气豪,腰横秋水雁翎刀. 风吹鼍鼓山河动,电闪旌旗日月高. 天上麒麟原有种,穴中蝼蚁岂能逃. 太平待诏归来日,朕与先生解战袍. 此处应该有掌声... 前言 读<学习JavaScr ...
- 重读《学习JavaScript数据结构与算法-第三版》-第2章 ECMAScript与TypeScript概述
定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据 ...
- 翻阅《数据结构与算法javascript描述》--数组篇
导读: 这篇文章比较长,介绍了数组常见的操作方法以及一些注意事项,最后还有几道经典的练习题(面试题). 数组的定义: JavaScript 中的数组是一种特殊的对象,用来表示偏移量的索引是该对象的属性 ...
- Java数据结构和算法(二)——数组
上篇博客我们简单介绍了数据结构和算法的概念,对此模糊很正常,后面会慢慢通过具体的实例来介绍.本篇博客我们介绍数据结构的鼻祖——数组,可以说数组几乎能表示一切的数据结构,在每一门编程语言中,数组都是重要 ...
- 数据结构1:数据结构与算法C语言版分析概述
本节开始将带领大家系统地学习数据结构,作为一门计算机专业大二学生的必修课程,该课程面对的目标人群为初步具备基本编程能力和编程思想的程序员(大一接触了 C 语言或者 C++).通过系统地学习数据结构,可 ...
- 重读《学习JavaScript数据结构与算法-第三版》- 第6章 链表(一)
定场诗 伤情最是晚凉天,憔悴厮人不堪言: 邀酒摧肠三杯醉.寻香惊梦五更寒. 钗头凤斜卿有泪,荼蘼花了我无缘: 小楼寂寞新雨月.也难如钩也难圆. 前言 本章为重读<学习JavaScript数据结构 ...
- 数据结构和算法(Java版)快速学习(数组Array)
Java数组 在Java中,数组是用来存放同一种数据类型的集合,注意只能存放同一种数据类型. 用类封装数组实现数据结构 数据结构必须具有以下基本功能: ①.如何插入一条新的数据项 ②.如何寻找某一特定 ...
- 数据结构(C语言第2版)-----数组,广义表,树,图
任何一个算法的设计取决于选定的数据结构,而算法的实现依赖于采用的存储结构. 之前线性表的数据元素都是非结构的原子类型,元素的值是不可再分的.下面学习的这两个线性表是很特殊的,其中数据元素本身也可能是一 ...
随机推荐
- 我常用的一些linux命令
之前做过两年的运维,用过很多命令,深切体会到某些linux命令熟练掌握后对效率提升有多大.举个简单的例子,在做了研发后经常会有跑一些数据,对于结果数据的处理,我们的产品同学一般都习惯于用excel做统 ...
- 懒人必备:.NetCore快速搭建ELK分布式日志中心
该篇内容由个人博客点击跳转同步更新!转载请注明出处! 前言 ELK是什么 它是一个分布式日志解决方案,是Logstash.Elastaicsearch.Kibana的缩写,可用于从不同的服务中收集日志 ...
- odoo12从零开始:一、安装odoo运行环境(mac)
写在前面: 接触odoo已经两年多了,在大学做课程设计的时候,无意间了解到odoo这个erp框架,当时的odoo在国内还默默无闻,我也不曾想过自己毕业后会从事到odoo框架的相关开发工作中来.两年多的 ...
- HDU - 4358 Boring counting (dsu on tree)
Boring counting: http://acm.hdu.edu.cn/showproblem.php?pid=4358 题意: 求一棵树上,每个节点的子节点中,同一颜色出现k次 的 个数. 思 ...
- hdu 2767 Proving Equivalences(tarjan缩点)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2767 题意:问最少加多少边可以让所有点都相互连通. 题解:如果强连通分量就1个直接输出0,否者输出入度 ...
- 牛客练习赛51 A abc
A. abc 题意: 给出一个字符串s,你需要做的是统计s中子串”abc”的个数.子串的定义就是存在任意下标a<b<c,那么”s[a]s[b]s[c]”就构成s的一个子串.如”abc”的子 ...
- 接口请求失败处理,重新请求并限制请求次数.自己封装搞定retry函数
最近开发一款小程序的时候想到一个问题,如果接口突然挂掉怎么办呢,于是乎想到一个解决办法.接口请求重试功能.并限制请求次数 用最新的async函数语法实现.代码简洁明了. 测试代码如下: functio ...
- Day002_LInux基础_常用命令
#空格和tab键↓↓mkdir 创建目录 ↓ls list 显示目录里面的内容详情↓cd change directory 切换目录,进入到目录↓pwd 显示当前所在路径 ,定位↓###绝对路径和相对 ...
- Spring Boot2 系列教程(四)理解Spring Boot 配置文件 application.properties
在 Spring Boot 中,配置文件有两种不同的格式,一个是 properties ,另一个是 yaml . 虽然 properties 文件比较常见,但是相对于 properties 而言,ya ...
- MultipartFile 获取上传TXT文件字数
@ResponseBody @RequestMapping(value = "/addImgForDynamic")//(发布动态) public Map addImgForDyn ...