稀疏矩阵
稀疏数组就是数组中大部分的内容值都未被使用(为零为null或相同值),在数组中仅有少部分的空间使用。因此造成内存空间的浪费,为了节省内存空间,并且不影响数组中原有的内容值,我们可以采用一种压缩的方式来表示稀疏数组的内容。
应用场景
大量冗余的相同数据存储,将数据进行压缩
描述
稀疏矩阵至少有一行,列数一定为三。
稀疏矩阵的第一行存放二维数组的行数、列数以及非零值的个数【稀疏矩阵的行数 - 1】
稀疏矩阵的第二行开始 存放各个值所对应的坐标【行索引、列索引】和值的大小
C#示例源程序:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SparseMatrixDemo
{
class Program
{
static void Main(string[] args)
{
//源矩阵
int[,] srcMatrix = new int[7, 6];
srcMatrix[0, 3] = 1;
srcMatrix[1, 2] = 2;
srcMatrix[1, 5] = 88;
srcMatrix[2, 0] = 33;
srcMatrix[3, 1] = 5;
srcMatrix[4, 2] = 7;
srcMatrix[4, 3] = 98;
srcMatrix[5, 2] = 24;
srcMatrix[6, 0] = 18;
srcMatrix[6, 4] = 9;
Console.WriteLine("源矩阵的内容...");
PrintMatrix(srcMatrix);
Console.WriteLine();
int[,] sparseMatrix = ConvertToSparseMatrix(srcMatrix);
Console.WriteLine("转化为稀疏矩阵的内容...");
PrintMatrix(sparseMatrix);
Console.WriteLine();
int[,] normalMatrix = ConvertToNormalMatrix(sparseMatrix);
Console.WriteLine("还原为初始矩阵的内容...");
PrintMatrix(normalMatrix);
Console.ReadLine();
}
/// <summary>
/// 打印矩阵
/// </summary>
/// <param name="matrix"></param>
static void PrintMatrix(int[,] matrix)
{
int rowCount = matrix.GetLength(0);
int columnCount = matrix.GetLength(1);
Console.WriteLine($"------矩阵有【{rowCount}】行【{columnCount}】列------");
for (int i = 0; i < rowCount; i++)
{
int[] rowArray = new int[columnCount];
for (int j = 0; j < columnCount; j++)
{
rowArray[j] = matrix[i, j];
}
Console.WriteLine(string.Join(" ", rowArray.Select(element => element.ToString("D2"))));
}
}
/// <summary>
/// 源矩阵 转化为 稀疏矩阵
/// </summary>
/// <param name="srcMatrix"></param>
/// <returns></returns>
static int[,] ConvertToSparseMatrix(int[,] srcMatrix)
{
int rowCount = srcMatrix.GetLength(0);
int columnCount = srcMatrix.GetLength(1);
int totalCount = 0;
//元组的第一个代表行索引,第二个代表列索引,第三个代表 当前值
List<Tuple<int, int, int>> tuples = new List<Tuple<int, int, int>>();
for (int i = 0; i < rowCount; i++)
{
for (int j = 0; j < columnCount; j++)
{
if (srcMatrix[i, j] != 0)
{
totalCount++;
tuples.Add(Tuple.Create(i, j, srcMatrix[i, j]));
}
}
}
//稀疏矩阵 : 行数-【totalCount+1】,列数【3】
//稀疏数组第一行存放二维数组的行数和列数以及非零值的个数
//第二行开始 存放各个值所对应的坐标【行索引、列索引】和具体值
int[,] sparseMatrix = new int[totalCount + 1, 3];
//第一行 进行统计
sparseMatrix[0, 0] = rowCount;
sparseMatrix[0, 1] = columnCount;
sparseMatrix[0, 2] = totalCount;
//第二行 存放行索引、列索引、具体值
for (int i = 0; i < totalCount; i++)
{
sparseMatrix[i + 1, 0] = tuples[i].Item1;
sparseMatrix[i + 1, 1] = tuples[i].Item2;
sparseMatrix[i + 1, 2] = tuples[i].Item3;
}
return sparseMatrix;
}
/// <summary>
/// 稀疏矩阵 转化为 源矩阵
/// </summary>
/// <param name="sparseMatrix">稀疏矩阵的列数一定为三,至少有一行</param>
/// <returns></returns>
static int[,] ConvertToNormalMatrix(int[,] sparseMatrix)
{
int row = sparseMatrix.GetLength(0);
int column = sparseMatrix.GetLength(1);
if (row < 1)
{
throw new Exception("【非法】稀疏矩阵至少有一行");
}
if (column != 3)
{
throw new Exception("【非法】稀疏矩阵有且只有三列");
}
int rowCount = sparseMatrix[0, 0];
int columnCount = sparseMatrix[0, 1];
int totalCount = sparseMatrix[0, 2];
int[,] srcMatrix = new int[rowCount, columnCount];
//稀疏矩阵的第一列代表行索引,第二列代表列索引,第三列代表 当前值
for (int i = 0; i < totalCount; i++)
{
srcMatrix[sparseMatrix[i + 1, 0], sparseMatrix[i + 1, 1]] = sparseMatrix[i + 1, 2];
}
return srcMatrix;
}
}
}