特殊矩阵——对称矩阵(Symmetric Matrix)

特殊矩阵——对称矩阵(Symmetric Matrix)

注:压缩存储的矩阵可以分为特殊矩阵和稀疏矩阵。对于那些具有相同元素或零元素在矩阵中分布具有一定规律的矩阵,被称之为特殊矩阵。对于那些零元素数据远远多于非零元素数目,并且非零元素的分布没有规律的矩阵称之为稀疏矩阵。

1. 对称矩阵的概念

  • 元素以主对角线为对称轴对应相等的矩阵。

2. 对称矩阵的特性

  • 对角矩阵都是对称矩阵,对称矩阵必须是方形矩阵。
  • 设一个n*n的方阵A,对于矩阵A中的任一元素 aij ,当且仅当 aij = aji 时(0≤i≤n-1,0≤j≤n-1)时,矩阵A为对称矩阵。

3. 对称矩阵的压缩存储

  • 可以利用对称矩阵的上述特性,只存储对角线及对角线以下的元素,或者只存储对角线及对角线以上的元素,前者称之为下三角阵,后者称之为上三角阵。
    特殊矩阵——对称矩阵(Symmetric Matrix)_第1张图片
  • 对一个n*n的对称方阵A,元素总数有 n2 个,而上三角阵或下三角阵的元素共有n+(n-1)+(n-2)+……+2+1=n*(n+1)/2个元素。因此,存储对称方阵时最多只需存储n*(n+1)/2个元素。
  • 利用对称矩阵的对称性,可以用一维数组B存储对称矩阵A(这主要要区分四种存储方式:行优先方式存储下三角阵、行优先方式存储上三角阵、列优先方式存储下三角阵和列优先方式存储上三角阵)。
    (1)行优先方式存储下三角阵
    特殊矩阵——对称矩阵(Symmetric Matrix)_第2张图片
    (2)行优先方式存储上三角阵
    特殊矩阵——对称矩阵(Symmetric Matrix)_第3张图片
    (3)列优先方式存储下三角阵
    特殊矩阵——对称矩阵(Symmetric Matrix)_第4张图片
    (4)列优先方式存储上三角阵
    特殊矩阵——对称矩阵(Symmetric Matrix)_第5张图片

4. 特殊矩阵的实现

  • 文件:SymmetricMatrix.h

    
    #include 
    
    
    using namespace std;
    
    //压缩存储后,存储对称方阵时最多只需存储n*(n+1)/2个元素
    
    #define GetTotalLen(n) n * (n + 1) / 2              
    
    
    //按行优先方式存放下三角阵时,矩阵元素下标对应的一维数组的下标
    
    #define GetIndexRowLower(i, j) ((i + 1) * i) / 2 + j    
    
    
    //按行优先方式存放上三角阵时,矩阵元素下标对应的一维数组的下标
    //n * i + j - ((i + 1) * i) / 2 =>((2 * n - i - 1) * i) / 2 + j
    
    #define GetIndexRowUpper(n, i, j) ((2 * n - i - 1) * i) / 2 + j 
    
    
    //按列优先方式存放下三角阵时,矩阵元素下标对应的一维数组的下标
    //n * j + i - ((j + 1) * j) / 2 =>((2 * n - j - 1) * j) / 2 + i 
    
    #define GetIndexColLower(n, i, j) ((2 * n - j - 1) * j) / 2 + i 
    
    
    //按列优先方式存放上三角阵时,矩阵元素下标对应的一维数组的下标
    
    #define GetIndexColUpper(i, j) ((j + 1) * j) / 2 + i    
    
    
    class SymmetricMatrix
    {
    public:
        SymmetricMatrix(int order);
    
        ~SymmetricMatrix();
    
    public:
        void create();                          //创建矩阵
    
        void destroy();                         //销毁矩阵
    
        void transpos();                        //矩阵转置
    
        int get_order();                        //获取矩阵阶数
    
        int* compressed_storage_row_lower();    //压缩存储特殊矩阵——对称矩阵,按行优先方式存放下三角阵
    
        int* compressed_storage_row_upper();    //压缩存储特殊矩阵——对称矩阵,按行优先方式存放上三角阵
    
        int* compressed_storage_col_lower();    //压缩存储特殊矩阵——对称矩阵,按列优先方式存放下三角阵
    
        int* compressed_storage_col_upper();    //压缩存储特殊矩阵——对称矩阵,按列优先方式存放上三角阵
    
        bool is_symmetric();                    //判断矩阵是否为对称矩阵
    
    public:
        friend ostream& operator<<(ostream& os, SymmetricMatrix& m);    //输出矩阵
    
    private:
        int _order;
        int **_matrix;
    };
  • 文件:SymmetricMatrix.cpp

    
    #include "SymmetricMatrix.h"
    
    
    SymmetricMatrix::SymmetricMatrix(int order)
    : _order(order), _matrix(new int*[order])
    {
        create();
    }
    
    SymmetricMatrix::~SymmetricMatrix()
    {
        destroy();
    }
    
    void SymmetricMatrix::create()
    {
        for (int i = 0; i < _order; i++)
        {
            _matrix[i] = new int[_order];
            for (int j = 0; j < _order; j++)
            {
                _matrix[i][j] = i + j;
            }
        }
    }
    
    void SymmetricMatrix::destroy()
    {
        for (int i = 0; i < _order; i++)
        {
            delete[] _matrix[i];
        }
        delete[] _matrix;
        _matrix = NULL;
    }
    
    void SymmetricMatrix::transpos()
    {
        int temp = 0;
        for (int i = 0; i < _order; i++)
        {
            for (int j = 0; j < _order; j++)
            {
                temp = _matrix[i][j];
                _matrix[i][j] = _matrix[j][i];
                _matrix[j][i] = temp;
            }
        }
    }
    
    int SymmetricMatrix::get_order()
    {
        return _order;
    }
    
    int* SymmetricMatrix::compressed_storage_row_lower()
    {
        int index = 0;
        int total_count = GetTotalLen(_order);
        int *a = new int[total_count];
        for (int i = 0; i < _order; i++)
        {
            for (int j = 0; j <= i; j++)
            {
                index = GetIndexRowLower(i, j);
                a[index] = _matrix[i][j];
            }   
        }
        return a;
    }
    
    int* SymmetricMatrix::compressed_storage_row_upper()
    {
        int index = 0;
        int total_count = GetTotalLen(_order);
        int *a = new int[total_count];
        for (int i = 0; i < _order; i++)
        {
            for (int j = i; j < _order; j++)
            {
                index = GetIndexRowUpper(_order, i, j);
                a[index] = _matrix[i][j];
            }   
        }
        return a;
    }
    
    int* SymmetricMatrix::compressed_storage_col_lower()
    {
        int index = 0;
        int total_count = GetTotalLen(_order);
        int *a = new int[total_count];
        for (int j = 0; j < _order; j++)
        {
            for (int i = j; i < _order; i++)
            {
                index = GetIndexColLower(_order, i, j);
                a[index] = _matrix[i][j];
            }
        }
        return a;
    }
    
    int* SymmetricMatrix::compressed_storage_col_upper()
    {
        int index = 0;
        int total_count = GetTotalLen(_order);
        int *a = new int[total_count];
        for (int j = 0; j < _order; j++)
        {
            for (int i = 0; i <= j; i++)
            {
                index = GetIndexColUpper(i, j);
                a[index] = _matrix[i][j];
            }
        }
        return a;
    }
    
    bool SymmetricMatrix::is_symmetric()
    {
        for (int i = 0; i < _order; i++)
        {
            for (int j = 0; j < _order; j++)
            {
                if (_matrix[i][j] != _matrix[j][i])
                {
                    return false;
                }
            }
        }
        return true;
    }
    
    ostream& operator<<(ostream& os, SymmetricMatrix& m)
    {
        for (int i = 0; i < m._order; i++)
        {
            for (int j = 0; j < m._order; j++)
            {
                os << m._matrix[i][j] << " ";
            }
            os << endl;
        }
        return os;
    }
  • 文件:main.cpp

    
    #include "SymmetricMatrix.h"
    
    
    int main()
    {
        int n = 0;
        cout << "请输入对称矩阵的阶数,n = ";
        cin >> n;
    
        SymmetricMatrix matrix(n);
        if (true == matrix.is_symmetric())
        {
            cout << "$ 输出对称矩阵:" << endl;
            cout << matrix;//或operator<<(cout, matrix);
        }
    
        matrix.transpos();
        if (true == matrix.is_symmetric())
        {
            cout << "$ 输出转置后的对称矩阵:" << endl;
            cout << matrix;//或operator<<(cout, matrix);
        }
    
        cout << "\n$ 输出压缩存储后的一维数组(按行优先方式存放下三角阵):" << endl;
        int *arrayrl = matrix.compressed_storage_row_lower();
        for (int i = 0; i < GetTotalLen(matrix.get_order()); i++)
        {
            cout << arrayrl[i] << " ";
        }
        cout << endl;
        delete[] arrayrl;
    
        cout << "\n$ 输出压缩存储后的一维数组(按行优先方式存放上三角阵):" << endl;
        int *arrayru = matrix.compressed_storage_row_upper();
        for (int i = 0; i < GetTotalLen(matrix.get_order()); i++)
        {
            cout << arrayru[i] << " ";
        }
        cout << endl;
        delete[] arrayru;
    
        cout << "\n$ 输出压缩存储后的一维数组(按列优先方式存放下三角阵):" << endl;
        int *arraycl = matrix.compressed_storage_col_lower();
        for (int i = 0; i < GetTotalLen(matrix.get_order()); i++)
        {
            cout << arraycl[i] << " ";
        }
        cout << endl;
        delete[] arraycl;
    
        cout << "\n$ 输出压缩存储后的一维数组(按列优先方式存放上三角阵):" << endl;
        int *arraycu = matrix.compressed_storage_col_upper();
        for (int i = 0; i < GetTotalLen(matrix.get_order()); i++)
        {
            cout << arraycu[i] << " ";
        }
        cout << endl;
        delete[] arraycu;
    
        system("pause");
        return 0;
    }

参考文献:
[1]《数据结构(用面向对象方法与C++语言描述)(第2版)》殷人昆——第四章
[2] 百度搜索关键字:对称矩阵

你可能感兴趣的:(C++数据结构)