我们知道矩阵是一个非常强大的数据结构,在动态规划以及各种图论算法上都有广泛的应用,当然矩阵有着不足的地方就是空间和时间

复杂度都维持在N2上,比如1w个数字建立一个矩阵,在内存中会占用1w*1w=1亿的类型空间,这时就会遇到outofmemory。。。那么面

临的一个问题就是如何来压缩矩阵,当然压缩的方式有很多种,这里就介绍一个顺序表的压缩方式:三元组。

一:三元组

有时候我们的矩阵中只有零星的一些非零元素,其余的都是零元素,那么我们称之为稀疏矩阵,当然没有绝对的说有多少个零元素才算稀疏。

针对上面的这个无规律的存放非零元素,三元组提出了一种方法,就是仅仅记录矩阵中的非零元素以及它的行,列以及值N(x,y,v)构成的一个三元

组,标识一个稀疏矩阵的话,还要记录该矩阵的阶数,这样我们就将一个二维的变成了一个一维,极大的压缩的存储空间,这里要注意的就是,三

元组的构建采用“行“是从上到下,“列”也是从左到右的方式构建的顺序表。

/// <summary>/// 三元组/// </summary>public class Unit{public int x;public int y;public int element;}/// <summary>/// 标识矩阵/// </summary>public class SPNode{//矩阵总行数public int rows;//矩阵总列数public int cols;//非零元素的个数public int count;//矩阵中非零元素public List<Unit> nodes = new List<Unit>();}

其实说到这里也就差不多了,我们只要知道三元组是用来做矩阵压缩的一个顺序存储方式即可,然后知道怎么用三元组表来做一些常规的矩阵

运算,好了,既然说已经做成线性存储了,那就做个“行列置换”玩玩。

二:行列置换

做行列置换很容易,也就是交换"非零元素"的(x,y)坐标,要注意的就是,原先我们的三元组采用的是”行优先“,所以在做转置的时候需要

遵循"列优先“。

/// <summary>/// 行转列运算/// </summary>/// <param name="spNode"></param>/// <returns></returns>public SPNode ConvertSpNode(SPNode spNode){//矩阵元素的x和y坐标进行交换SPNode spNodeLast = new SPNode();//行列互换spNodeLast.rows = spNode.cols;spNodeLast.cols = spNode.rows;spNodeLast.count = spNode.count;//循环原矩阵的列数 (行列转换)for (int col = 0; col < spNode.cols; col++){//循环三元组行的个数for (int sp = 0; sp < spNode.count; sp++){var single = spNode.nodes[sp];//找到三元组中存在的相同编号if (col == single.y){spNodeLast.nodes.Add(new Unit(){x = single.y,y = single.x,element = single.element});}}}return spNodeLast;}

最后是总的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Threading;
using System.IO;namespace ConsoleApplication2
{public class Program{public static void Main(){Martix martix = new Martix();//构建三元组var node = martix.Build();foreach (var item in node.nodes){Console.WriteLine(item.x + "\t" + item.y + "\t" + item.element);}Console.WriteLine("******************************************************");var mynode = martix.ConvertSpNode(node);foreach (var item in mynode.nodes){Console.WriteLine(item.x + "\t" + item.y + "\t" + item.element);}Console.Read();}}public class Martix{/// <summary>/// 三元组/// </summary>public class Unit{public int x;public int y;public int element;}/// <summary>/// 标识矩阵/// </summary>public class SPNode{//矩阵总行数public int rows;//矩阵总列数public int cols;//非零元素的个数public int count;//矩阵中非零元素public List<Unit> nodes = new List<Unit>();}/// <summary>/// 构建一个三元组/// </summary>/// <returns></returns>public SPNode Build(){SPNode spNode = new SPNode();//遵循行优先的原则spNode.nodes.Add(new Unit() { x = 0, y = 0, element = 8 });spNode.nodes.Add(new Unit() { x = 1, y = 2, element = 1 });spNode.nodes.Add(new Unit() { x = 2, y = 3, element = 6 });spNode.nodes.Add(new Unit() { x = 3, y = 1, element = 4 });//4阶矩阵spNode.rows = spNode.cols = 4;//非零元素的个数spNode.count = spNode.nodes.Count;return spNode;}/// <summary>/// 行转列运算/// </summary>/// <param name="spNode"></param>/// <returns></returns>public SPNode ConvertSpNode(SPNode spNode){//矩阵元素的x和y坐标进行交换SPNode spNodeLast = new SPNode();//行列互换spNodeLast.rows = spNode.cols;spNodeLast.cols = spNode.rows;spNodeLast.count = spNode.count;//循环原矩阵的列数 (行列转换)for (int col = 0; col < spNode.cols; col++){//循环三元组行的个数for (int sp = 0; sp < spNode.count; sp++){var single = spNode.nodes[sp];//找到三元组中存在的相同编号if (col == single.y){spNodeLast.nodes.Add(new Unit(){x = single.y,y = single.x,element = single.element});}}}return spNodeLast;}}
}

经典算法题每日演练——第二十题 三元组相关推荐

  1. 经典算法题每日演练——第二十二题 奇偶排序

    原文:经典算法题每日演练--第二十二题 奇偶排序 这个专题因为各种原因好久没有继续下去了,MM吧...你懂的,嘿嘿,不过还得继续写下去,好长时间不写,有些东西有点生疏了, 这篇就从简单一点的一个&qu ...

  2. 经典算法题每日演练——第十题 树状数组

    原文:经典算法题每日演练--第十题 树状数组 有一种数据结构是神奇的,神秘的,它展现了位运算与数组结合的神奇魅力,太牛逼的,它就是树状数组,这种数据结构不是神人是发现不了的. 一:概序 假如我现在有个 ...

  3. 经典算法题每日演练——第二十四题 梳排序

    这篇再看看一个经典的排序,梳排序,为什么取名为梳,可能每个梳都有自己的gap吧,大梳子gap大一点,小梳子gap小一点. 上一篇我们看到鸡尾酒排序是在冒泡排序上做了一些优化,将单向的比较变成了双向,同 ...

  4. 经典算法题每日演练——第二十一题 十字链表

    上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法"十字链表",当然目的都是一样,压缩空间. 一:概念 既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下5个元素(ro ...

  5. 经典算法题每日演练——第十九题 双端队列

    经典算法题每日演练--第十九题 双端队列 原文:经典算法题每日演练--第十九题 双端队列 话说大学的时候老师说妹子比工作重要~,工作可以再换,妹子这个...所以...这两个月也就一直忙着Fall in ...

  6. 经典算法题每日演练——第六题 协同推荐SlopeOne 算法

    原文:经典算法题每日演练--第六题 协同推荐SlopeOne 算法 相信大家对如下的Category都很熟悉,很多网站都有类似如下的功能,"商品推荐","猜你喜欢&quo ...

  7. 经典算法题每日演练——第七题 KMP算法

    原文:经典算法题每日演练--第七题 KMP算法 在大学的时候,应该在数据结构里面都看过kmp算法吧,不知道有多少老师对该算法是一笔带过的,至少我们以前是的, 确实kmp算法还是有点饶人的,如果说红黑树 ...

  8. 经典算法题每日演练——第三题 猴子吃桃

    猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个.第二天早上又将剩下的桃子吃了一半,还是不过瘾又多 吃了一个.以后每天都吃前一天剩下的一半再加一个.到第10天刚好剩一个.问猴子第一天摘了多 ...

  9. 经典算法题每日演练——第十一题 Bitmap算法

    在所有具有性能优化的数据结构中,我想大家使用最多的就是hash表,是的,在具有定位查找上具有O(1)的常量时间,多么的简洁优美, 但是在特定的场合下: ①:对10亿个不重复的整数进行排序. ②:找出1 ...

  10. 经典算法题每日演练——第五题 字符串相似度

    原文地址:http://www.cnblogs.com/huangxincheng/archive/2012/11/11/2765633.html 这篇我们看看最长公共子序列的另一个版本,求字符串相似 ...

最新文章

  1. 漫画:什么是动态规划?
  2. .NET Core 2.0体验
  3. webdriverAPI-Java
  4. Windows FFMPEG开发环境配置
  5. mac上SVN简单几个命令
  6. cad插件制作教程_CAD电子签名制作教程
  7. [svn] 解决SVN冲突攻略(手册)
  8. Oracle 服务作用
  9. [转]Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
  10. 简单的linux下docker的下载与安装
  11. FTP 客户端C实现
  12. Python 数值求解偏微分方程(含两个示例)
  13. 阿里云商标注册续展有哪几种?阿里云商标注册续展有优惠券吗?
  14. 程序包解析错误解决办法
  15. 解决 Successfully created project '' on GitHub, but initial push failed: Could not read from remote
  16. PS2键盘扫描码:通码与断码
  17. PC 版微信多开防撤回软件
  18. 对话新经济人物|知道创宇杨冀龙:无边界网络时代已来,“零信任”正重构安防体系...
  19. 人大金仓国产化数据库适配
  20. 关爱青少年作品,灯塔

热门文章

  1. ModuleNotFoundError: No module named 'cv2' (安装cv2)
  2. 例2.4 Day of Week - 九度教程第7题(日期类问题)
  3. php 未定义偏移,错误php未定义的偏移:2-3-4等
  4. 谷歌离开游览器不触发_谷歌推广应该怎么做,一篇文章带你了解谷歌推广
  5. php公众号第三方登录,微信公众号开发小记——3.接入三方登录
  6. python 参数一样结果不一样_优化Keras的超参数:相同参数的结果不同
  7. 尚学人工智能课程---2、算法工程师和大数据介绍
  8. 《亿万僵尸》优优卡评测:用你智慧的大脑,制定一套战争策略,把僵尸一举歼......
  9. Apache服务器和tomcat服务器有什么区别(转)
  10. 《指针的编程艺术(第二版)》一2.3 三颗星星:表示三把钥匙