資料結構七:矩陣
1. 矩陣的定義
矩陣可以描述為一個二元陣列,矩陣的下標通常從1開始。下面是利用上節提到的行優先對映的方法來對矩陣進行實現。
1.1 矩陣的實現
#pragma once
#include <iostream>
//矩陣類
template<typename elemType>
class Matirx
{
protected:
//矩陣的資料成員
elemType* elems;//儲存矩陣元素
int rows, cols;//矩陣的行和列
private:
//抽象資料型別及過載編譯系統的預設方法宣告
Matirx(int rs, int cs);//建構函式
~Matirx();//解構函式
int getRows() const;//返回矩陣的行數
int getCols() const;//返回矩陣的列數
elemType& operator()(int i, int j);
Matirx(const Matirx<elemType> & copy);
Matirx<elemType>& operator=(const Matirx<elemType> & copy);
};
template<typename elemType>
Matirx<elemType>::Matirx(int rs, int cs)
{
if ( rs > 0 && cs > 0)
{
elems = new elemType[rs * cs];
rows = rs;
cols = cs;
}
else
{
std::cout << "行數或列數無效!" << std::endl;
}
}
template<typename elemType>
Matirx<elemType>::~Matirx()
{
if (elems != NULL) delete []elems;
}
template<typename elemType>
int Matirx<elemType>::getRows() const
{
return rows;
}
template<typename elemType>
int Matirx<elemType>::getCols() const
{
return cols;
}
template<typename elemType>
elemType& Matirx<elemType>::operator()(int i, int j)
{
if (i < 1 || i > rows || j < 1 || j > cols)
{
std::cout << "下標越界!" << std::endl;
}
else
{
return elems[(i-1)*cols + j - 1]
}
}
template<typename elemType>
Matirx<elemType>::Matirx(const Matirx<elemType> & copy)
{
rows = copy.rows;
cols = copy.cols;
elems = new elemType[rows * cols];
for (int i = 0; i < rows*cols; i++)
{
elems[i] = copy.elems[i];
}
}
template<typename elemType>
Matirx<elemType>& Matirx<elemType>::operator=(const Matirx<elemType> & copy)
{
if (© != this)
{
if (elems != NULL) delete[]elems;
rows = copy.rows;
cols = copy.cols;
elems = new elemType[rows * cols];
for (int i = 0; i < rows*cols; i++)
{
elems[i] = copy.elems[i];
}
}
}
2.特殊矩陣
如果值相同元素或者零元素在矩陣中按一定的規律分佈,這樣的矩陣稱為特殊矩陣。
下面介紹一些基本概念:
方陣:行數和列數相同矩陣,下面介紹的矩陣都是特殊矩陣。
對稱矩陣:對於對稱陣,對於所有的
和
有
.
三對角陣:當
時有
(或為常數c)。
下三角陣:當
時有
(或為常數c)。
上三角陣:當
時有
(或為常數c)。
2.1 三對角矩陣
在
的矩陣中,三條對角線之外的元素為0或者為常數c。
主對角線: 主對角線上的元素行列座標滿足
.
低對角線:主對角線之下的對角線,其上的元素行列座標滿足
。
高對角線:主對角線之上的對角線,其上的元素行列座標滿足
。
主對角線上有n個元素,兩個次對角線上有n-1個元素,所以這三條對角線上有3n-2個元素,加上其他位置的元素都是常數c,因此共需要3n-1個儲存單元來儲存。現在關鍵要做的是如何把這含有3n-1個元素的一維陣列與矩陣的行列下標建立對映關係。
這裡就有三種不同的對映方式:
(1)將常量c放到elems[0]的位置,其他元素按照行優先的方式對映到陣列elems中。
(2)將常量c放到elems[0]的位置,其他元素按照先高對角線再主對角線最後低對角線方式對映到陣列elems中。
(3)將常量c放到elems[0]的位置,其他元素按照列優先的方式對映到陣列elems中。
實際應用中可以自行選擇。
下面的實現採用的是方式二。
//三對角矩陣類
template<typename elemType>
class TriDiagonalMatrix
{
protected:
//成員變數
elemType* elems;//儲存矩陣元素
int n;//矩陣階數
private:
TriDiagonalMatrix(int sz);//構造階數為sz的三對角陣
~TriDiagonalMatrix();//解構函式
int getSize() const;//獲取矩陣的階數
elemType& operator()(int i, int j);//過載函式運算子
TriDiagonalMatrix(const TriDiagonalMatrix<elemType>& copy);//複製建構函式
TriDiagonalMatrix<elemType>& operator=(const TriDiagonalMatrix<elemType> ©);
};
template<typename elemType>
TriDiagonalMatrix<elemType>::TriDiagonalMatrix(int sz)
{
if (sz < 1)
{
std::cout << "矩陣階數不能小於1!" << std::endl;
}
else
{
n = sz;
elems = new elemType[3 * n - 1];
}
}
template<typename elemType>
TriDiagonalMatrix<elemType>::~TriDiagonalMatrix()
{
if (elems != NULL) delete []elems;
}
template<typename elemType>
int TriDiagonalMatrix<elemType>::getSize() const
{
return n;
}
template<typename elemType>
elemType& TriDiagonalMatrix<elemType>::operator()(int i, int j)
{
if (i<1 || i>n || j<1 || j>n)
{
std::cout << "下標出界!" << std::endl;
}
else
{
if (i == j - 1) return elems[i];//高對角線元素
else if (i == j) return elems[n + i - 1];//i才從1開始,主對角線
else if (i == j - 1) return elems[2 * n + i - 2];
else return elems[0];
}
}
template<typename elemType>
TriDiagonalMatrix<elemType>::TriDiagonalMatrix
(const TriDiagonalMatrix<elemType>& copy)
{
n = copy.n;
elems = new elemType[3 * n - 1];
for (int i = 0; i < 3 * n - 1; i++)
{
elems[i] = copy.elems[i];
}
}
template<typename elemType>
TriDiagonalMatrix<elemType>& TriDiagonalMatrix<elemType>::operator=
(const TriDiagonalMatrix<elemType> ©)
{
if (© != this)
{
if (elems != NULL) delete[]elems;
n = copy.n;
elems = new elemType[3 * n - 1];
for (int i = 0; i < 3 * n - 1; i++)
{
elems[i] = copy.elems[i];
}
}
}
2.2 三角矩陣
三角矩陣的非常數的元素的個數為:
所以共需要要
個儲存單元,一般將常數儲存在elems[0].
接下來採用行優先對映,來看看各類三角矩陣的對映關係。
(1)對於下三角矩陣
在一維陣列中的位置為:
(2)對於上三角,我們採用列優先的方式,這樣對映關係與上面是一樣的。
(3)對於對稱矩陣,採用行優先的方式:
a(i,j)在elems中的位子為: