数据结构:对称矩阵

数据结构 专栏收录该内容
20 篇文章 0 订阅

矩阵

一、什么是矩阵?

矩阵就是一个二维数组,有行和列之分

二、矩阵的分类?

对称矩阵、稀疏矩阵

三、什么是特殊矩阵?

1.特殊矩阵是矩阵;
2.矩阵中的元素有许多值相同或者有许多零元素;
3.矩阵中值相同的元素或零元素,它们的分布是有一定规律的;
ps:这三个条件缺一不可

对称矩阵

一、什么是对称矩阵?

1.对称矩阵是矩阵的一种存在形式
2.设一个N*N的矩阵A,A中任意元素A(i,j),当且仅当A(i,j)=A(j,i)(0 <=i <=N-1&&
0 <=j <=N-1),则矩阵A是对称矩阵

这里写图片描述
ps:以矩阵的对角线为分割,分为上三角和下三角

二、对称矩阵的特性?

1.对称矩阵是一个方阵,即就是行和列长度相等
2.对称矩阵中的所有元素都是相互对称的,即就是矩阵的下三角和上三角是对称的

三、对阵矩阵中元素的位置

1.行=列时,此时表明此元素位于对角线
2.行>列时,表明此元素位于下三角中
3.行<列时,表明此元素位于上三角中

四、对称矩阵的存储

因为对称矩阵的上三角和下三角是相互对称的,所以只需要单独存储一个就好,可以单独存上三角或者单独存下三角

存储下三角:

    在存储下三角时,可以使用一个二维数组来保存矩阵中的数据,但是这样的
话,会造成空间的浪费,所以可以选择使用一个一维数组来压缩的存储下三角
    存储矩阵下三角元素个数等于((1+N)N)/2,所以数组的空间大小就
为((1+N)N)/2

核心代码:

for (size_t i = 0; i < N; ++i) { //存储行
            for (size_t j = 0; j <= i; ++j) { //存储列
                _array[index++] = array[(i*N) + j];

五、对称矩阵的访问

    由于在存储时,只存储了一个下三角,但是对阵矩阵的访问必须可以访问整
个矩阵,所以此时我们必须可以把整个矩阵还原

访问下三角中的元素时:

可以直接访问,因为存储的时候就是存了下三角
需要访问那个元素时,只需要把此元素之前的所有元素都偏移过去,就可以得到此元素了

访问上三角中的元素时:

由于在存储时,只存储了下三角,但是上三角的元素和下三角的元素是相互对称的,所以如果需要访问上三角的元素时,那就先把需要访问的元素对称到下三角,然后在访问下三角即可

访问函数:

T &Acess(size_t row, size_t col) {
        if (row < col)
            swap(row, col);
        return _array[(((row + 1)*row) >> 1) + col];
    }

源代码

#include <iostream>
#include <vector>
using namespace std;
template<class T>
class SymmetricMatrix {
public:
    SymmetricMatrix(const T *array, size_t N)
        :_row(N)
        , _col(N) {
        size_t index = 0;//是一维数组的下标
        _array.resize(((1 + N) * N) >> 1); //开辟空间,矩阵下三角元素共有((1 + N)N) / 2
        for (size_t i = 0; i < N; ++i) { //存储行
            for (size_t j = 0; j <= i; ++j) { //存储列
                _array[index++] = array[(i*N) + j];//二维数组在内存中,其实也是按一位数组的形式存储着的
            }
        }
    }
    T &Acess(size_t row, size_t col) {
        if (row < col)//如果是要访问上三角的元素,那就把需要访问的元素对称到下三角中,然后访问下三角
            swap(row, col);
        return _array[(((row + 1)*row) >> 1) + col];
    }
    void Print() { //打印矩阵
        for (size_t i = 0; i < _row; ++i) {
            for (size_t j = 0; j < _col; ++j)
                cout << Acess(i, j);
            cout << endl;
        }
        cout << endl;
    }
private:
    vector<T> _array;//用来存储矩阵下三角的一维数组
    size_t _row;//矩阵的行
    size_t _col;//矩阵的列

};
void TestSymmetricMatrix() {
    int array[5][5] = {
        { 0, 1, 2, 3, 4 },
        { 1, 0, 1, 2, 3 },
        { 2, 1, 0, 1, 2 },
        { 3, 2, 1, 0, 1 },
        { 4, 3, 2, 1, 0 }
    };
    SymmetricMatrix<int>  sm((int *)array, sizeof(array) / sizeof(array[0]));
    //因为array是二维数组,而构造函数的参数是一维数组,所以需要把二维的数组array强转为一位数组
    //注意二维数组名代表的是二维数组首元素的地址,只是此处说的首元素是二维数组首行
    cout << "下标为(3,2)的元素为:>   " << sm.Acess(3, 2) << endl;
    cout << "下标为(2,3)的元素为:>   " << sm.Acess(2, 3) << endl;
    sm.Print();
    cout << endl;
}
int main() {
    TestSymmetricMatrix();
    system("pause");
    return 0;
}

运行结果:
这里写图片描述

  • 6
    点赞
  • 4
    评论
  • 32
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值