当前位置: 首页 > news >正文

工业设计服务平台泰安网站建设推广优化

工业设计服务平台,泰安网站建设推广优化,wordpress 下一页 模板,深圳市企业网站建设价格上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法“十字链表”,当然目的都是一样,压缩空间。 一、概念 既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下 5 个元素(row,col,val,down,right),其中&…

上一篇我们看了矩阵的顺序存储,这篇我们再看看一种链式存储方法“十字链表”,当然目的都是一样,压缩空间。

一、概念

既然要用链表节点来模拟矩阵中的非零元素,肯定需要如下 5 个元素(row,col,val,down,right),其中:

row:矩阵中的行。
col:矩阵中的列。
val:矩阵中的值。
right:指向右侧的一个非零元素。
down:指向下侧的一个非零元素。

image.png
现在我们知道单个节点该如何表示了,那么矩阵中同行的非零元素的表示不就是一个单链表吗?比如如下:
image.png
那么进一步来说一个多行的非零元素的表示不就是多个单链表吗,是的,这里我把单链表做成循环链表,我们来看看如何用十字链表来表示稀疏矩阵。
image.png
从上面的十字链表中要注意两个问题:
第一:这里有一个填充色的节点,是十字链表中的总结点,它是记录该矩阵中的(row,col,value)和一个指向下一个头节点的 next 指针。
第二:每个链表都有一个头指针,总结点用 next 指针将它们贯穿起来。

二、操作

2.1、数据结构

刚才也说了,十字链表的总结点有一个 next 指针,而其他非零节点没有,所以为了方便,我们用一个 Unit 类包装起来。

 #region 单一节点/// <summary>/// 单一节点/// </summary>public class Node{//行号public int rows;//列号public int cols;//向下的指针域public Node down;//向右的指针域public Node right;//单元值(头指针的next和val)public Unit unit;}#endregion#region 统一“表头节点”和“非零节点”/// <summary>/// 统一“表头节点”和“非零节点”/// </summary>public class Unit{//表头节点的next域public Node next;//非零元素的值public int value;}#endregion

2.2、初始化

这一步,我们初始化总结点,并且用 next 指针将每个单链表的头节点链接成单链表(也就是上图中十字链表的第一行)

#region 十字链表中的“行数,列数,非零元素个数”/// <summary>/// 十字链表中的“行数,列数,非零元素个数”/// </summary>/// <param name="rows"></param>/// <param name="cols"></param>/// <param name="count"></param>public void Init(int rows, int cols, int count){var len = Math.Max(rows, cols) + 1;//从下标1开始算起nodes = new Node[len];//十字链表的总头节点nodes[0] = new Node();nodes[0].rows = rows;nodes[0].cols = cols;nodes[0].unit = new Unit(){value = count,next = null,};//down和right都指向自身nodes[0].right = nodes[0];nodes[0].down = nodes[0];var temp = nodes[0];//初始化多条链表的头结点for (int i = 1; i < len; i++){nodes[i] = new Node();nodes[i].rows = 0;nodes[i].cols = 0;nodes[i].unit = new Unit(){value = 0,next = temp.unit.next};//给上一个节点的next域赋值temp.unit.next = nodes[i];//将当前节点作为下一次循环的上一个节点temp = nodes[i];nodes[i].right = nodes[i];nodes[i].down = nodes[i];}}#endregion

2.3、插入节点

根据插入节点的 row 和 col 将节点插入到十字链表中指定的位置即可。

#region 插入十字链表中/// <summary>/// 插入十字链表中/// </summary>/// <param name="nums">矩阵</param>/// <param name="rows">矩阵的行数</param>/// <param name="cols">矩阵的列数</param>/// <param name="count">非0元素个数</param>/// <returns></returns>public Node[] Insert(int[,] nums, int rows, int cols, int count){//初始化操作Init(rows, cols, count);//插入操作for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){//直插入"非0元素"if (nums[i, j] != 0){var node = new Node();node.rows = i + 1;node.cols = j + 1;node.unit = new Unit(){value = nums[i, j]};node.right = node;node.down = node;InsertNode(node);}}}return nodes;}#endregion

2.4、打印链表

我们只要遍历每行链表的 right 指针即可。

#region 打印十字链表/// <summary>/// 打印十字链表/// </summary>/// <param name="nodes"></param>public void Print(Node[] nodes){var head = nodes[0];//遍历每一行的rightfor (int i = 1; i < head.rows + 1; i++){var p = nodes[i];while (p.right != nodes[i]){Console.WriteLine("({0},{1})\tval => {2}",p.right.rows,p.right.cols,p.right.unit.value);//指向下一个节点p = p.right;}}}#endregion

2.5、总的代码:

 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(){Crosslist crosslist = new Crosslist();int[,] nums = {{2,0,4 },{0,3,0 },{0,0,9 }};var nodes = crosslist.Insert(nums, 3, 3, 4);crosslist.Print(nodes);Console.Read();}}/// <summary>/// 十字链表/// </summary>public class Crosslist{#region 单一节点/// <summary>/// 单一节点/// </summary>public class Node{//行号public int rows;//列号public int cols;//向下的指针域public Node down;//向右的指针域public Node right;//单元值(头指针的next和val)public Unit unit;}#endregion#region 统一“表头节点”和“非零节点”/// <summary>/// 统一“表头节点”和“非零节点”/// </summary>public class Unit{//表头节点的next域public Node next;//非零元素的值public int value;}#endregionNode[] nodes;#region 十字链表中的“行数,列数,非零元素个数”/// <summary>/// 十字链表中的“行数,列数,非零元素个数”/// </summary>/// <param name="rows"></param>/// <param name="cols"></param>/// <param name="count"></param>public void Init(int rows, int cols, int count){var len = Math.Max(rows, cols) + 1;//从下标1开始算起nodes = new Node[len];//十字链表的总头节点nodes[0] = new Node();nodes[0].rows = rows;nodes[0].cols = cols;nodes[0].unit = new Unit(){value = count,next = null,};//down和right都指向自身nodes[0].right = nodes[0];nodes[0].down = nodes[0];var temp = nodes[0];//初始化多条链表的头结点for (int i = 1; i < len; i++){nodes[i] = new Node();nodes[i].rows = 0;nodes[i].cols = 0;nodes[i].unit = new Unit(){value = 0,next = temp.unit.next};//给上一个节点的next域赋值temp.unit.next = nodes[i];//将当前节点作为下一次循环的上一个节点temp = nodes[i];nodes[i].right = nodes[i];nodes[i].down = nodes[i];}}#endregion#region 在指定的“行,列”上插入节点/// <summary>/// 在指定的“行,列”上插入节点/// </summary>/// <param name="node"></param>/// <returns></returns>public void InsertNode(Node node){//先定位行Node pnode = nodes[node.rows];//在指定的“行”中找,一直找到该行最后一个节点(right指针指向自己的为止)while (pnode.right != nodes[node.rows] && pnode.right.cols < node.cols)pnode = pnode.right;//将最后一个节点的right指向插入节点的right,以此达到是循环链表node.right = pnode.right;//将插入节点给最后一个节点的right指针上pnode.right = node;//再定位列pnode = nodes[node.cols];//同理while (pnode.down != nodes[node.cols] && pnode.down.rows < node.rows){pnode = pnode.down;}node.down = pnode.down;pnode.down = node;}#endregion#region 插入十字链表中/// <summary>/// 插入十字链表中/// </summary>/// <param name="nums">矩阵</param>/// <param name="rows">矩阵的行数</param>/// <param name="cols">矩阵的列数</param>/// <param name="count">非0元素个数</param>/// <returns></returns>public Node[] Insert(int[,] nums, int rows, int cols, int count){//初始化操作Init(rows, cols, count);//插入操作for (int i = 0; i < rows; i++){for (int j = 0; j < cols; j++){//直插入"非0元素"if (nums[i, j] != 0){var node = new Node();node.rows = i + 1;node.cols = j + 1;node.unit = new Unit(){value = nums[i, j]};node.right = node;node.down = node;InsertNode(node);}}}return nodes;}#endregion#region 打印十字链表/// <summary>/// 打印十字链表/// </summary>/// <param name="nodes"></param>public void Print(Node[] nodes){var head = nodes[0];//遍历每一行的rightfor (int i = 1; i < head.rows + 1; i++){var p = nodes[i];while (p.right != nodes[i]){Console.WriteLine("({0},{1})\tval => {2}",p.right.rows,p.right.cols,p.right.unit.value);//指向下一个节点p = p.right;}}}#endregion}}

image.png

http://www.yayakq.cn/news/104223/

相关文章:

  • 怎么做网站和服务器吗自动化的网站建设
  • 茂名住房和城乡建设厅网站免费企业网站建设免费
  • 贵州建设水利厅考试网站抖音小程序广告怎么跳过
  • 网站建设资料 优帮云温州大型网站设计公司
  • 嘉兴网站建设技术托管自己做网站花多少钱
  • 公司做网站多少钱乐器如果让你建设一个网站
  • 怎样自学做网站重庆网站开发解决方案
  • 林和西网站建设赤峰微信网站建设
  • 宁波公司核名网站郑州网站建设网页设计
  • wordpress建图片网站网站建设的原则 流程
  • 电子商务网站规划myeclipse网站开发
  • 做网站西安品牌广告和效果广告的区别
  • 网页设计与网站建设考试wordpress 怎么通过数据库该域名
  • 简单的网站作业中国移动app免费下载
  • 网站连接数据库失败怎么办建设银行官网首页
  • 深圳商城网站建设建筑用网包括哪些
  • 做的比较漂亮的网站wordpress 农家乐
  • 苏州企业建设网站价格手机海报制作免费软件
  • wordpress手机端样式北京seo代理公司
  • 视频网站开发的视频放在哪建筑公司企业如何成功
  • 网站建设移交手续上海官方网站建设
  • 佛山网站建设方案wordpress 安卓 源码
  • 长沙企业网站建设较好的公司凌风科技wordpress
  • 网站建设所用软件关于建设校园网站申请报告
  • 织梦网站建设视频wordpress音乐
  • windowxp做网站服务器阿里云虚拟主机购买
  • 哪些网站做的比较好朝阳凌源网站建设
  • 重庆模板建站公司wordpress加上qq登录
  • dw做网站首页代码上海比较有名的外贸公司
  • 做网站可以用思源字体吗网站建设案例教程视频教程