資料結構八:稀疏矩陣(涉及三元組,十字連結串列)
阿新 • • 發佈:2019-01-12
###1. 稀疏矩陣的定義
稀疏矩陣是零元素居多的矩陣,稀疏矩陣和稠密矩陣之間並沒有一個精確的界限。假設m行n列的矩陣含有t個非零元素,一般稱
為稀疏因子。一般認為
的矩陣為稀疏矩陣。
稀疏矩陣常用的儲存方式是通過三元組來進行儲存。也就是對於每個非零元素,用三元組(行號,列號,值)來表示。接下來可以使用順序表或者連結串列的方式來儲存這些三元組,具體實現如下:
實現的時候主要注意設定指定位置(r, c)的元素值v時,應該首先查詢是否在三元組中有指定的三元組。如果存在,當v=0時,則刪除此三元組;否則,修改三元組的的非零元素值。如果不存在指定位置的三元組,當v = 0時不做任何操作,否則插入三元組。
#pragma once
#define DEFAULT_ROWS 10
#define DEFAULT_COLS 10
#define DEFAULT_SIZE 10
//三元組類
template<typename elemType>
struct Triple
{
//資料成員
int rows, cols;
elemType value;
//
Triple();//無參建構函式
Triple(int rs, int cs, elemType v)
{
rows = rs; cols = cs; value = v;
}
};
//稀疏矩陣三元組順序表類
template< typename elemType>
class TriSparseMatirx
{
protected:
//資料成員
Triple<elemType>* elems;
int maxSize; //非零元素的最大個數
int rows, cols, num;//稀疏矩陣的行數列數以及已存入的非零元素的個數
public:
TriSparseMatirx(int rs = DEFAULT_ROWS, int cs = DEFAULT_COLS,
int size = DEFAULT_SIZE);
~TriSparseMatirx();
int getRows() const;//返回稀疏矩陣的行數
int getCols() const;//返回稀疏矩陣的列數
int getNum() const;//返回稀疏矩陣非零元素的個數
bool setElem(int r, int c, const elemType& v);//設定指定位置的元素
bool getElem(int r, int c, elemType& v);//獲取指定位置的元素的值
TriSparseMatirx(const TriSparseMatirx<elemType>& copy);
TriSparseMatirx<elemType>& operator=(const TriSparseMatirx<elemType>& copy);
};
template<typename elemType>
TriSparseMatirx<elemType>::TriSparseMatirx(int rs , int cs ,int size )
{
//這個地方加一下對rs,cs的判斷
rows = rs;
cols = cs;
maxSize = size;
num = 0;
elems = new Triple<elemType>[maxSize];
}
template<typename elemType>
TriSparseMatirx<elemType>::~TriSparseMatirx()
{
if (elems != NULL) delete []elems;
}
template<typename elemType>
int TriSparseMatirx<elemType>::getRows() const
{
return rows;
}
template<typename elemType>
int TriSparseMatirx<elemType>::getCols() const
{
return cols;
}
template<typename elemType>
int TriSparseMatirx<elemType>::getNum() const
{
return num;
}
template<typename elemType>
bool TriSparseMatirx<elemType>::setElem(int r, int c, const elemType& v)
{
if (r<1 || r>rows || c<1 || c>cols)
{
return false;
}
int i, j;
for (j = num - 1; j >= 0 && r < elems[j].rows || r == elems[j].rows
&& c < elems[j].cols; j--);//查詢三元組位置
if (j>=0 && elems[j].rows == r || elems[j].cols == c)
{ //找到三元組
if (v == 0)
{ //刪除三元組
for (i = j + 1; i < num;i++)
{
elems[i - 1] = elems[i];
}
num--;
}
else
{
elems[j].value = v;
}
return true;
}
else if(v != 0)//如果沒有找到且v不為0則插入
{
if (num < maxSize)
{//將三元組插入到三元組表中
for (i = num - 1; i > j;i--)
{
elems[i + 1] = elems[i]
}
//j+1為空的位置插入元素
elems[j + 1], rows = r;
elems[j + 1].cols = c;
elems[j + 1].value = v;
num++;
return true;
}
else
{
return false;
}
}
}
template<typename elemType>
bool TriSparseMatirx<elemType>::getElem(int r, int c, elemType& v)
{
if (r<1 || r>rows || c<1 || c>cols)
{
return false;
}
int i, j;
for (j = num - 1; j >= 0 && r < elems[j].rows || r == elems[j].rows
&& c < elems[j].cols; j--);//查詢三元組位置
if (j >= 0 && elems[j].rows == r || elems[j].cols == c)
{
v = elems[j].value;
return true;
}
else
{
return false;
}
}
template<typename elemType>
TriSparseMatirx<elemType>::TriSparseMatirx(const TriSparseMatirx<elemType>& copy)
{
maxSize = copy.maxSize;
elems = new Triple<elemType>[maxSize];
num = copy.num
for (int i = 0; i < num;i++)
{
elems[i] = copy.elems[i];
}
}
template<typename elemType>
TriSparseMatirx<elemType>& TriSparseMatirx<elemType>::operator=(const TriSparseMatirx<elemType>& copy)
{
if (© != this)
{
maxSize = copy.maxSize;
elems = new Triple<elemType>[maxSize];
num = copy.num
for (int i = 0; i < num; i++)
{
elems[i] = copy.elems[i];
}
}
return *this;
}
2矩陣的轉置
如果矩陣是用二維陣列表示的,則轉置操作很簡單。轉置操作主要是將每個元素的行號和列號互換。由於在三元組表中,元素按行號或者列號排列,所以在行號或列號交換之後,還要調整元素的位置,使其仍按行序或列序進行排列。轉置的具體步驟如下:
(1)將每個非零元素對應的三元組的行號和列號進行互換。
(2)對三元組重新排序,使其中的元素按行序或者列序排列。
如果要降低演算法的時間複雜度,這時可以開闢一個新的三元組表,假設原三元組表為source,轉置後的三元組為dest,具體步驟如下:
(1)將三元組表source中的每個元素取出交換其行號和列號。
(2)將變換後的三元組存入目標dest三元組表中適當位置,使dest中的元素按照行序或者列序進行排列。