javascript实现数据结构:稀疏矩阵的十字链表存储表示

当矩阵的非零个数和位置在操作过程中变化大时,就不宜采用顺序存储结构来表示三元组的线性表。例如,在作“将矩阵B加到矩阵A上”的操作时,由于非零元的插入或删除将会引起A.data中元素的移动。为此,对这种类型的矩阵,采用链式存储结构表示三元组的线性表更为恰当。

在链表中,每个非陵园可用一个含5个域的结点表示,其中i,j和e这3个域分别表示该非零元所在的行,列和非零元的值,向右域right用以链接同一行中下一个非零元,向下域down用以链接同一列中下一个非零元。同一行的非零元通过right域链接成一个线性表,同一列中的非零元通常down域链接成一个线性链表,每一个非零元既是某个行链表中的一个结点,又是某个列链表中的一个结点,整个矩阵构成了一个十字交叉的链表。

可用两个分别存储行链表的头指针和列链表的头指针的一维数组来表示。

代码:


  1 /**
2 * 十字链表
3 *
4 * 当矩阵的非零个数和位置在操作过程中变化大时,就不宜采用顺序存储结构来表示三元组的线性表。例如,在作“将矩阵B加到矩阵A上”的操作时,由于非零元的插入或删除将会引起A.data中元素的移动。为此,对这种类型的矩阵,采用链式存储结构表示三元组的线性表更为恰当。
5 *
6 * 在链表中,每个非陵园可用一个含5个域的结点表示,其中i,j和e这3个域分别表示该非零元所在的行,列和非零元的值,向右域right用以链接同一行中下一个非零元,向下域down用以链接同一列中下一个非零元。同一行的非零元通过right域链接成一个线性表,同一列中的非零元通常down域链接成一个线性链表,每一个非零元既是某个行链表中的一个结点,又是某个列链表中的一个结点,整个矩阵构成了一个十字交叉的链表。
7 *
8 * 可用两个分别存储行链表的头指针和列链表的头指针的一维数组来表示。
9 */
10
11 // 稀疏矩阵的十字链表存储表示
12
13 function OLNode(i, j, e) {
14 // 该非零元的行和列下标
15 this.i = i || 0;
16 this.j = j || 0;
17 this.e = e;
18 // 该非零元所在行表和列表的后继链域
19 this.right = null; // type: OLNode
20 this.down = null; // type: OLNode
21 }
22
23 function CrossList() {
24 // 行和列链表头指针向量基址由CreateSMatrix分配
25 this.rhead = [];
26 this.chead = [];
27 // 稀疏矩阵的行数,列数
28 this.mu = 0;
29 this.nu = 0;
30 this.tu = 0;
31 }
32 /**
33 * 矩阵初始化
34 * @param m
35 * @param n
36 * @param t
37 * @param {Array} list 二维数组,每行的元素分别是[i, j, e]
38 */
39 CrossList.prototype.createSMatrix = function (m, n, t, list) {
40 this.mu = m;
41 this.nu = n;
42 this.tu = t;
43
44 for (var row = 0; row < list.length; row++) {
45 var p = {};
46 OLNode.apply(p, list[row]);
47 var i = list[row][0];
48 var j = list[row][1];
49 var q;
50
51 if (this.rhead[i] == null || this.rhead[i].j > j) {
52 p.right = this.rhead[i];
53 this.rhead[i] = p;
54 } else {
55 // 查询在行表中的插入位置
56 for (q = this.rhead[i]; q.right && q.right.j < j; q = q.right);
57 p.right = q.right;
58 q.right = p;
59 }
60
61 if (this.chead[j] == null || this.chead[j].i > i) {
62 p.down = this.chead[j];
63 this.chead[j] = p;
64 } else {
65 for (q = this.chead[j]; q.down && q.down.i < i; q = q.down);
66 p.down = q.down;
67 q.down = p;
68 }
69 }
70 };
71
72 // 矩阵相加
73 CrossList.prototype.addMatrix = function (crossList) {
74 var hl = [];
75 //hl初始化
76 for (var j = 0; j <= this.nu; j++)
77 hl[j] = this.chead[j];
78
79 for (var i = 0; i <= this.mu; i++) {
80 //pa和pb指向每一行的第一个非0元结点,直至最后一行
81 var pa = this.rhead[i];
82 var pb = crossList.rhead[i];
83 var pre = null;
84
85 //处理B的一行,直至本行中无非0元素的结点
86 while (pb) {
87 var p, q;
88 // 新插入一个结点到pa的左侧
89 if (!pa || pa.j > pb.j) {
90 p = new OLNode(pb.i, pb.j, pb.e);
91
92 //行表的指针变化
93 if (!pre) this.rhead[p.i] = p;
94 else pre.right = p;
95
96 p.right = pa;
97 pre = p;
98
99 //列表的指针变化
100 if (hl[p.j]) {
101 // 从hl[p.j]开始找到新结点在同一列中的前驱结点,并让hl[p.j]指向它
102 for (q = hl[p.j]; q && q.i < p.i;q = q.down)
103 hl[p.j] = q;
104 }
105
106 //在列表中插入新结点,根据行数判断插入前面还是后面
107 if (!this.chead[p.j] || this.chead[p.j].i > p.i) {
108 p.down = this.chead[p.j];
109 this.chead[p.j] = p;
110 } else {
111 p.down = hl[p.j].down;
112 hl[p.j].down = p;
113 }
114
115 hl[p.j] = p;
116 pb = pb.right;
117 } else if (pa.j < pb.j) {
118 pre = pa;
119 pa = pa.right;
120 } else {
121 //当pa.j === pb.j时,将B中当前结点的值加到A中当前结点上
122 pa.e += pb.e;
123
124 //当pa.e === 0时,删除该结点
125 if (pa.e === 0) {
126 // 若无前驱结点,将第一个非0元结点置为当前结点的后继结点,
127 // 否则前驱结点的后继结点为当前结点的后继结点
128 if (!pre) this.rhead[pa.i] = pa.right;
129 else pre.right = pa.right;
130
131 p = pa;
132 pa = pa.right;
133
134 //列表的指针变化
135 if (hl[p.j]) {
136 //从hl[p.j]开始找到新结点在同一列中的前驱结点,并让hl[p.j]指向它
137 for (q = hl[p.j]; q && q.i < p.i; q = q.down)
138 hl[p.j] = q;
139 }
140
141 if (this.chead[p.j] == p)
142 this.chead[p.j] = hl[p.j] = p.down;
143 else
144 hl[p.j].down = p.down;
145 }
146
147 pb = pb.right;
148 }
149 }
150 }
151 };
152
153 var lists = [
154 [1, 4, 5],
155 [2, 2, -1],
156 [1, 1, 3],
157 [3, 1, 2]
158 ];
159 var a = new CrossList();
160 a.createSMatrix(4, 4, 4, lists);
161 console.log(a);
162
163 var lists2 = [
164 [1, 4, -5],
165 [2, 3, 1],
166 [1, 1, 3],
167 [3, 2, 2]
168 ];
169 var b = new CrossList();
170 b.createSMatrix(4, 4, 4, lists2);
171 console.log(b);
172
173 a.addMatrix(b);
174 console.log(a);

时间: 2024-10-23 02:50:40

javascript实现数据结构:稀疏矩阵的十字链表存储表示的相关文章

稀疏矩阵的十字链表存储表示

/* Name: 稀疏矩阵的十字链表存储表示 Copyright: Author: 巧若拙 Date: 29-10-14 21:25 Description: //------------------------------------------------------------------------- 除了用三元组顺序表来存储压缩矩阵,我们还可以用链表结构来存储,实际上后者应用更广泛, 因为当非零元素的数目较大时,三元组的时间复杂度实在太高.链表结构中最常见的是十字链表, 在十字链表中,

数据结构之---C/C++实现稀疏矩阵的十字链表

首先这里介绍什么是矩阵的十字链表,大家可以理解稀疏矩阵是顺序存储的,那么这个就是链式存储的. 如图: 存储该矩阵 那么应该是如下的格式: 我们知道稀疏矩阵的三元组存储方式的实现很简单,每个元素有三个域分别是col,row, e.代表了该非零元的行号.列号以及值.那么在十字链表的存储方式下,首先这三个域是肯定少不了的,不然在进行很多操作的时候都要自己使用计数器,很麻烦.而十字链表的形式大家可以理解成每一行是一个链表,而每一列又是一个链表 通过上面的图我们可以知道,每个结点不止要存放row, col

数据结构之---C++语言实现图的十字链表存储表示

最近一直忙着考研复习,很久都没有更新博客了,今天写一篇数据结构的存储. //有向图的十字链表存储表示 //杨鑫 #include <iostream> #include <cstdio> #include <stdlib.h> #include <cstring> using namespace std; #define MAX_VERTEX_NUM 20 #define OVERFLOW -2 #define OK 1 typedef int Status

7-3-有向图的十字链表存储结构-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第7章  图 - 有向图的十字链表存储结构 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.Scanf.c.LinkQueue.c        

看数据结构写代码(21) 稀疏矩阵(十字链表方式)

写完 这个样例,花费了 我不少时间.大部分时间 花费在 调试 内存问题上. 比如在销毁十字链表时.多次释放节点空间,造成 _CrtIsValidHeapPointer(pUserData) 异常. 当使用malloc 分配 一个 空间时,会将这个空间的起始地址和长度 加到一个链表中去.free(p)的时候 ,会从 链表里 查找 是否 有 这个地址空间,找到了就将这个节点从链表中删除._CrtIsValidHeapPointer(pUserData)  这个函数 正是 检查 这个空间是否 在链表里

javascript实现数据结构: 串的块链存储表示

和线性表的链式存储结构相类似,也可采用链式方式存储串值.由于串结构的特殊性--结构中的每个数据元素是一个字符,则用链表存储串值时,存在一个"结点大小"的问题,即每个结点可以存放一个字符,也可以存放多个字符. 下面是结点大小为4(即每个结点存放4个字符)的链表: head --> (a) --> (b) --> (c) --> ... --> (i) 当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上

【算法与数据结构】图 -- 十字链表

图的[十字链表]表示法是一种链式存储结构,可以看成是[邻接表]和[逆邻接表]的组合 本文中用到的有向图 /************************************************************************ 有向图的存储:十字链表 有向图的十字链表存储结构,是有一种链式存储结构,可以看成是[邻接表]和[逆邻接表] 的结合. 图中每条弧对应一个[弧结点],每个顶点对应一个[顶点结点] 弧结点 -------------------------------

javascript实现数据结构: 稀疏矩阵之三元组线性表表示

稀疏矩阵(Sparse Matrix):对于稀疏矩阵,目前还没有一个确切的定义.设矩阵A是一个n*m的矩阵中有s个非零元素,设  δ=s/(n*m),称δ为稀疏因子, 如果某一矩阵的稀疏因子δ满足δ≦0.05时称为稀疏矩阵, 稀疏矩阵的压缩存储 对于稀疏矩阵,采用压缩存储方法时,只存储非0元素.必须存储非0元素的行下标值.列下标值.元素值.因此,一个三元组(i, j, aij)唯一确定稀疏矩阵的一个非零元素. 上图的稀疏矩阵A的三元组线性表为: ( (1,2,12), (1,3,9), (3,1

有向图的十字链表存储形式

十字链表是有向图的另一种链式存储结构.可以看成是将有向图的邻接表和逆邻接表(只考虑入度)结合起来得到的一种链表.在十字链表中,对应于有向图中每一个顶点有一个节点,每一条弧也有一个结点. 顶点之间是数组顺序存储,而弧是链式存储. 弧结点结构: 顶点结点结构: 十字链表形态: 实现: /*********************************************** 有向图的存储形式--十字链表 by Rowandjj 2014/6/27 ***********************