矩阵的存储及转置算法.docx

上传人:b****2 文档编号:1260169 上传时间:2023-04-30 格式:DOCX 页数:15 大小:58.87KB
下载 相关 举报
矩阵的存储及转置算法.docx_第1页
第1页 / 共15页
矩阵的存储及转置算法.docx_第2页
第2页 / 共15页
矩阵的存储及转置算法.docx_第3页
第3页 / 共15页
矩阵的存储及转置算法.docx_第4页
第4页 / 共15页
矩阵的存储及转置算法.docx_第5页
第5页 / 共15页
矩阵的存储及转置算法.docx_第6页
第6页 / 共15页
矩阵的存储及转置算法.docx_第7页
第7页 / 共15页
矩阵的存储及转置算法.docx_第8页
第8页 / 共15页
矩阵的存储及转置算法.docx_第9页
第9页 / 共15页
矩阵的存储及转置算法.docx_第10页
第10页 / 共15页
矩阵的存储及转置算法.docx_第11页
第11页 / 共15页
矩阵的存储及转置算法.docx_第12页
第12页 / 共15页
矩阵的存储及转置算法.docx_第13页
第13页 / 共15页
矩阵的存储及转置算法.docx_第14页
第14页 / 共15页
矩阵的存储及转置算法.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

矩阵的存储及转置算法.docx

《矩阵的存储及转置算法.docx》由会员分享,可在线阅读,更多相关《矩阵的存储及转置算法.docx(15页珍藏版)》请在冰点文库上搜索。

矩阵的存储及转置算法.docx

矩阵的存储及转置算法

矩阵的存储及转置算法

本文要点:

1.对称矩阵与稀疏矩阵

2.两种矩阵的压缩存储

3.代码实现两种矩阵

对称矩阵

1.对称矩阵也是一种特殊矩阵,满足Aij=Aji(设矩阵为A,且有0<=i

2.对称矩阵的压缩存储

如果把矩阵中的每个元素都存储起来,那么就会显得浪费空间,因为每两个关于对角线对称的元素相等,因此就可以将矩阵压缩存储到一个数组Array中,即:

将对称的两个元素存一份,对角线上的元素都存储起来,也就是说只存储上三角或下三角,那么存储的元素的总个数就为n(n+1)/2个,这样,当n特别大的时候,也就最有效。

压缩存储的数组与矩阵之间满足:

Array[i*(i+1)/2+j]=Martix[i][j](下三角存储i>=j)

3.代码实现

[cpp] viewplain copy

 

1.template  

2.class SymmetryMatrix  

3.{  

4.public:

  

5.    SymmetryMatrix(const T* a,size_t n)  

6.        :

_matrix(new T[n*(n+1)/2])  

7.        ,_size(n*(n+1)/2)  

8.        ,_n(n)  

9.    {  

10.        size_t index = 0;   //表示一维数组的下标  

11.        for (size_t i=0; i

12.        {  

13.            for (size_t j=0; j

14.            {  

15.                if (i >= j)      //存储下三角  

16.                {  

17.                    _matrix[index++] = a[i*n+j];  

18.                    //index++;  

19.                }  

20.                else  

21.                    continue;  

22.            }  

23.        }  

24.    }  

25.  

26.    T& Access(size_t row,size_t col)    //访问数据  

27.    {  

28.        if (row < col)  

29.        {  

30.            std:

:

swap(row,col);  

31.        }  

32.        return _matrix[row*(row+1)/2+col];  

33.    }  

34.  

35.    void Display()  

36.    {  

37.        for (size_t i=0; i<_n; i++)  

38.        {  

39.            for (size_t j=0; j<_n; j++)  

40.            {  

41.                cout<

42.            }  

43.            cout<

44.        }  

45.    }  

46.protected:

  

47.    T* _matrix;     //压缩存储的一维数组  

48.    size_t _size;   //可存储的大小  

49.    size_t _n;      //行列的大小       

50.};  

稀疏矩阵

1.稀疏矩阵中,有效数据(非0)的数量远小于非法数据的个数(0为非法数据)

2.稀疏矩阵的存储也是压缩存储的,但与对称矩阵不同的地方有两点:

(1)稀疏矩阵的压缩存储只存储有效值;

(2)稀疏矩阵存储以行优先的顺序存储在三元组中,表示为:

{row,col,value},row和col分别表示该有效值的行和列。

一、存储及输出

存储的方法类似于对称矩阵的存储,但要将行和列也进行存储;

输出的时候多考虑表示数组的下标会不会越界

[cpp] viewplain copy

 

1.//数据的存储  

2.SpareMatrix(const T* a,size_t row,size_t col,const T& invalid)  

3.    :

_rowSize(row)  

4.    ,_colSize(col)  

5.    ,_invalid(invalid)  

6.{  

7.    for(size_t i=0; i

8.    {  

9.        for (size_t j=0; j

10.        {  

11.            if (a[i*col+j] !

= invalid)  //有效值  

12.            {  

13.                Triple t(i,j,a[i*col+j]);  

14.                t._value = a[i*col+j];  

15.                t._row = i;  

16.                t._col = j;  

17.                _martix.push_back(t);  

18.            }  

19.        }  

20.    }  

21.}  

22.//输出  

23.void Display()  

24.{  

25.    size_t index = 0;  

26.    for (size_t i=0; i<_rowSize; ++i)  

27.    {  

28.        for (size_t j=0; j<_colSize; ++j)  

29.        {  

30.            if (index < _martix.size()  

31.                && i == _martix[index]._row  

32.                && j == _martix[index]._col)  

33.            {  

34.                cout<<_martix[index]._value<<" ";  

35.                ++index;  

36.            }  

37.            else  

38.            {  

39.                cout<<0<<" ";  

40.            }  

41.        }  

42.        cout<

43.    }  

44.    cout<

45.}  

二、一般转置算法

从上图我们可以看出:

矩阵转置后,三元组中的顺序也发生了改变。

因此要得到矩阵M转置后的矩阵TM,我们只需将三元组的顺序改变就好了。

转置的三步:

a.将矩阵的行列交换

b.将每个三元组中的行、列交换

c.将原矩阵三元组的顺序重排得到新的三元组

[cpp] viewplain copy

 

1.SpareMatrix Transport()    //矩阵的转置  

2.{  

3.    SpareMatrix TSMartix;  

4.    TSMartix._rowSize = _colSize;//交换行列  

5.    TSMartix._colSize = _rowSize;  

6.    TSMartix._invalid = _invalid;  

7.    TSMartix._artix.reserve(_martix.size());  

8.  

9.    for (size_t col=0; col<_colSize; ++col)  //以列优先进行查找  

10.    {  

11.        for (size_t index=0; index<_martix.size(); ++index)  

12.        {  

13.            if (_martix[index]._col == col)  

14.            {  

15.                Triple tmp(_martix[index]._col,_martix[index]._row,_martix[index]._value);  

16.                TSMartix._tix.push_back(tmp);  

17.            }  

18.        }  

19.    }  

20.    return TSMartix;  

21.}  

这样算法即使可以得到结果,但是效率高不高呢?

算算时间复杂度--------

O(矩阵的列数*有效数值的个数),如果这个矩阵是500*500呢?

显然效率就会特别低了。

因此,我们就需要一种转置算法来提高效率。

三、快速转置

(假设原矩阵为M,转置后得到的矩阵为FSTM)

我们按照普通转置的算法,将M的三元组的次序进行转置,并将每次转置后的数据能直接放到FSTM三元组正确的位置。

但这种算法的前提是:

需要预先知道M每行的有效值个数,将M中第一个有效数放到正确位置后,并记下该位置,以后对M的三元组中的每个数进行转置时,都可以直接放到正确的位置。

引入两个量count和start,count-----记录每行的有效数据的个数

start-------表示每行第一个数的起始位置

分析上图我们可以得到:

start=上一行的起始位置+上一行的有效数个数

时间复杂度:

O(2*有效值的个数+列数)

代码实现:

[cpp] viewplain copy

 

1.SpareMatrix FastTransport()  

2.{  

3.    SpareMatrix FSTMartix;  

4.    FSTMartix._rowSize = _colSize;//交换行列  

5.    FSTMartix._colSize = _rowSize;  

6.    FSTMartix._invalid = _invalid;  

7.    FSTMartix._martix.resize(_martix.size());  

8.  

9.    int* count = new int[_colSize];  

10.    memset(count,0,_martix.size()*sizeof(int));  

11.    int* start = new int[_colSize];  

12.    memset(start,0,_martix.size()*sizeof(int));  

13.  

14.    //统计每列的有效值个数  

15.    for (size_t i=0; i<_martix.size(); ++i)  

16.    {  

17.        count[_martix[i]._col]++;  

18.    }  

19.  

20.    //计算每一列的起始位置  

21.    for (size_t j=1; j<_colSize; ++j)  

22.    {  

23.        start[j] = start[j-1] + count[j-1];//每一列起始位置=上一列起始位置+上一列有效数个数  

24.    }  

25.  

26.    //转置  

27.    for (size_t index=0; index<_martix.size(); ++index)  

28.    {  

29.        size_t tmp = _martix[index]._col;   //取到原三元组中每个数的列  

30.        FSTMartix._martix[start[tmp]]._col = _martix[index]._row;  

31.        FSTMartix._martix[start[tmp]]._row = _martix[index]._col;  

32.        FSTMartix._martix[start[tmp]]._value = _martix[index]._value;  

33.        ++start[tmp];   //start指针要向后移位  

34.    }  

35.    return FSTMartix;  

36.}  

 

稀疏矩阵代码的整体实现:

[cpp] viewplain copy

 

1.template  

2.struct Triple  

3.{  

4.    Triple(size_t row,size_t col,const T& value = T())  

5.        :

_row(row)  

6.        ,_col(col)  

7.        ,_value(value)  

8.    {}  

9.    Triple()  

10.    {}  

11.  

12.    size_t _row;    //行  

13.    size_t _col;    //列  

14.    T _value;       //有效值  

15.};  

16.  

17.template  

18.class SpareMatrix  

19.{  

20.public:

  

21.    SpareMatrix()  

22.        :

_martix(NULL)  

23.        ,_rowSize(0)  

24.        ,_colSize(0)  

25.        ,_invalid(T())  

26.    {}  

27.    //数据的存储  

28.    SpareMatrix(const T* a,size_t row,size_t col,const T& invalid)  

29.        :

_rowSize(row)  

30.        ,_colSize(col)  

31.        ,_invalid(invalid)  

32.    {  

33.        for(size_t i=0; i

34.        {  

35.            for (size_t j=0; j

36.            {  

37.                if (a[i*col+j] !

= invalid)  //有效值  

38.                {  

39.                    Triple t(i,j,a[i*col+j]);  

40.                    t._value = a[i*col+j];  

41.                    t._row = i;  

42.                    t._col = j;  

43.                    _martix.push_back(t);  

44.                }  

45.            }  

46.        }  

47.    }  

48.    //输出  

49.    void Display()  

50.    {  

51.        size_t index = 0;  

52.        for (size_t i=0; i<_rowSize; ++i)  

53.        {  

54.            for (size_t j=0; j<_colSize; ++j)  

55.            {  

56.                if (index < _martix.size()  

57.                    && i == _martix[index]._row  

58.                    && j == _martix[index]._col)  

59.                {  

60.                    cout<<_martix[index]._value<<" ";  

61.                    ++index;  

62.                }  

63.                else  

64.                {  

65.                    cout<<0<<" ";  

66.                }  

67.            }  

68.            cout<

69.        }  

70.        cout<

71.    }  

72.    SpareMatrix Transport()    //矩阵的转置  

73.    {  

74.        SpareMatrix TSMartix;  

75.        TSMartix._rowSize = _colSize;//交换行列  

76.        TSMartix._colSize = _rowSize;  

77.        TSMartix._invalid = _invalid;  

78.        TSMartix._martix.reserve(_martix.size());  

79.  

80.        for (size_t col=0; col<_colSize; ++col)  //以列优先进行查找  

81.        {  

82.            for (size_t index=0; index<_martix.size(); ++index)  

83.            {  

84.                if (_martix[index]._col == col)       

85.                {  

86.                    Triple tmp(_martix[index]._col,_martix[index]._row,_martix[index]._value);  

87.                    TSMartix._martix.push_back(tmp);  

88.                }  

89.            }  

90.        }  

91.        return TSMartix;  

92.    }  

93.  

94.    SpareMatrix FastTransport()  

95.    {  

96.        SpareMatrix FSTMartix;  

97.        FSTMartix._rowSize = _colSize;//交换行列  

98.        FSTMartix._colSize = _rowSize;  

99.        FSTMartix._invalid = _invalid;  

100.        FSTMartix._martix.resize(_martix.size());  

101.  

102.        int* count = new int[_colSize];  

103.        memset(count,0,_martix.size()*sizeof(int));  

104.        int* start = new int[_colSize];  

105.        memset(start,0,_martix.size()*sizeof(int));  

106.  

107.        //统计每列的有效值个数  

108.        for (size_t i=0; i<_martix.size(); ++i)  

109.        {  

110.            count[_martix[i]._col]++;  

111.        }  

112.  

113.        //计算每一列的起始位置  

114.        for (size_t j=1; j<_colSize; ++j)  

115.        {  

116.            start[j] = start[j-1] + count[j-1];//每一列起始位置=上一列起始位置+上一列有效数个数  

117.        }  

118.  

119.        //转置  

120.        for (size

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2