稀疏矩阵的压缩存储和转置

稀疏矩阵的特点:零元多,非零元远少于零元,存储数据没什么规律
因此可以采用只存储非零元素的方法来进行压缩存储(为了节省空间)。所以在进行压缩存储的时侯需要存储非零元素值的同时还要存储非零元素在矩阵中的位置,即非零元素所在的行号和列号,也就是在存储某个元素比如aij的值的同时,还需要存储该元素所在的行号i和它的列号j,这样就构成了一个三元组(row,col,value)的线性表。
也可以用链表实现,我这里用的是线性表

#include<iostream>
#include<vector>
using namespace std;

//稀疏矩阵的压缩存储及转置
template<class T>
struct Triple
{
    int _row;
    int _col;
    T _value;
    Triple (const T& value = T(), 
        int row = 0, int col = 0)
        :_value(value)
        ,_row(row)
        ,_col(col)
    {
    }
};
template<class T>
class coefficient_matrix
{
public :
    coefficient_matrix()
        :_colsize(0)
        ,_rowsize(0)
    {}
    //二维数组入顺序表
    coefficient_matrix(int* a,int row,int col,const int invalid )
        :_rowsize (row)
        ,_colsize (col)
        ,_invalid (invalid )
    {    
        for( int i = 0;i < row ; i++)
        {
            for(int j = 0;j <col  ; j++)
            {
                //压缩存储,只存储有效值
                if(a[col*i+j]!= invalid )                
                {
                    _a.push_back(Triple<T>(a[col*i+j],i,j));//将二维数组的有效值 尾插入 顺序表:有行,有列,有值
                }
            }
        }
    }

    void Display()
    {
        size_t index = 0;
        for(int i= 0;i<_rowsize ;i++)
        {
            for(int j= 0;j<_colsize ;j++)
            {
                if((index < _a.size ())&&(_a[index]._row == i)&&(_a[index]._col == j))
                {               
                    cout <<_a[index]._value<<" ";
                    index++;
                }
                else
                {
                    cout<<_invalid  <<" ";
                }
            }
            cout<<endl;
        }
        cout<<endl;
    }


    //普通转置   (时间复杂度: o(colSize*有效数据的个数))
    //coefficient_matrix<T> transport()
    //{
    //  coefficient_matrix<T> tmp;
    //  tmp._colsize = _rowsize ;
    //  tmp._rowsize = _colsize ;
    //  tmp._invalid = _invalid ;
    //  for(int i = 0; i< _colsize ;i++)
    //  {
    //      int index = 0;
    //      while(index < _a.size ())
    //      {
    //          if(_a[index ]._col==i)
    //          {
    //              Triple<T> t;
    //              t._col = _a[index ]._row;
    //              t._row = _a[index ]._col;
    //              t._value =_a[index ]._value;
    //              tmp._a.push_back (t);

    //          }
    //          index++;
    //      }
    //  }
    //  return tmp;
    //}


//快速转置
    coefficient_matrix<T> FastTransport()
    {
        coefficient_matrix<T> tmp;
        tmp._colsize = _rowsize;
        tmp._rowsize = _colsize;
        tmp._invalid = _invalid;

        int* rowCounts = new int[_colsize];
        int* rowStart = new int[_colsize];
        memset(rowCounts, 0, sizeof(int)*_colsize);
        memset(rowStart, 0, sizeof(int)*_colsize);

        int index = 0;
        while (index < _a.size())
        {
            rowCounts[_a[index]._col]++;
            ++index;
        }
        rowStart[0] = 0;
        for (size_t i = 1; i < _colsize; ++i)
        {
            rowStart[i] = rowStart[i-1] + rowCounts[i-1];
        }

        index = 0;

        //tmp._a.reserve(_a.size());
        tmp._a.resize(_a.size());

        while (index < _a.size())
        {
            size_t rowIndex = _a[index]._col;
            int& start = rowStart[rowIndex];

            Triple<T> t;
            t._value = _a[index]._value;
            t._row = _a[index]._col;
            t._col = _a[index]._row;
            tmp._a[start++] = t;

            ++index;

            /*tmp._a[(rowStart[_a[index]._col])++] = 
                Triple<T>(_a[index]._value, _a[index]._col, _a[index]._row);*/
        }

        return tmp;
    }

protected:
    vector<Triple<T>> _a;//结构体类型顺序表,三元组:位置,value
    int _rowsize;
    int _colsize;
    T _invalid;
};
int main()
{
    int arr[][4]=
    {
        {0,0,1,0},
        {0,2,0,0},
        {3,0,0,0}
    //{1, 0, 3, 0},
    //{0, 0, 0, 0},
    //{0, 0, 0, 0},
    //{2, 0, 4, 0},
    //{0, 0, 0, 0},
    //{0, 0, 0, 0}
    };
    coefficient_matrix<int> cm1((int*)arr,3,4,0);
    cm1.Display ();
    coefficient_matrix<int> cm2=cm1.FastTransport ();
    cm2.Display (); 

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值