矩陣快速轉置演算法詳解
阿新 • • 發佈:2018-12-17
矩陣的轉置實際上就是將資料元素的行標和列標互換,即 T(i,j) = M(j,i) 。例如:
圖1 矩陣的轉置
相應地,三元組錶轉變為: 圖2 三元組表
總結矩陣的轉置過程,共經歷了三個步驟:
矩陣轉置的快速轉置演算法和普通轉置演算法,區別就在於實現第 3 步的方法不同,快速轉置演算法在普通演算法的基礎上,對遍歷儲存的過程做了改進。下面我們對快速轉置演算法做詳細地講解。 首先將每一列中非 0 元素的個數對應地儲存在一個數組(陣列名為 array)中。在此基礎上,計算出每一列第一個元素存放在三元組表中的位置,儲存在陣列(陣列名為 cpot )中。 第一列第一個非 0 元素肯定存放在第一個位置,第二列第一個非 0 元素的位置 = 第一列存放的起始位置 + 第一列的非 0 元素個數,以此類推。
用圖 2 中置換之前的表舉例:
實現程式碼:
輸出結果
使用改進方法:
(1,3,6)(2,1,1)(2,2,3)(2,3,5) 這個演算法中含有四個並列的單迴圈,時間複雜度為
圖1 矩陣的轉置
相應地,三元組錶轉變為: 圖2 三元組表
總結矩陣的轉置過程,共經歷了三個步驟:
- 矩陣的行數 n 和列數 m 的值交換;
- 將三元組中的 i 和 j 調換;
- 轉換之後的表同樣按照行序(置換前的列序)為主序,進行排序;
矩陣轉置的快速轉置演算法和普通轉置演算法,區別就在於實現第 3 步的方法不同,快速轉置演算法在普通演算法的基礎上,對遍歷儲存的過程做了改進。下面我們對快速轉置演算法做詳細地講解。 首先將每一列中非 0 元素的個數對應地儲存在一個數組(陣列名為 array)中。在此基礎上,計算出每一列第一個元素存放在三元組表中的位置,儲存在陣列(陣列名為 cpot )中。 第一列第一個非 0 元素肯定存放在第一個位置,第二列第一個非 0 元素的位置 = 第一列存放的起始位置 + 第一列的非 0 元素個數,以此類推。
用圖 2 中置換之前的表舉例:
array 陣列中的資料表示,第一列有一個非 0 元素,第二列中 3 個非0元素。
cpot 陣列中的資料表示,第一列中第一個資料儲存的位置預設是 1 ,第二列第一個非 0 元素存放的位置是 2。
計算方法是:cpot[col] = cpot[col-1] + array[col-1],即後邊一列第一個非 0 元素存放的位置為前邊一列第一個非 0 元素存放的位置加上該列非 0 元素的個數的和。 在以上兩個陣列的基礎上,當遍歷表 a 的 j 列時,根據每個元素 j 列的數值,就可以判斷出它在表 b 中的存放位置,整個三元組表只需要遍歷一次,就能實現矩陣的轉置。實現程式碼:
#include<stdio.h> #define number 10 typedef struct { int i,j; int data; }triple; typedef struct { triple data[number]; int rpos[number]; int n,m,num; }TSMatrix; TSMatrix fastTransposeMatrix(TSMatrix M,TSMatrix T){ T.m=M.n; T.n=M.m; T.num=M.num; if (T.num) { int array[number]; for (int col=1; col<=M.m; col++) { array[col]=0; } for (int t=0; t<M.num; t++) { int j=M.data[t].j; array[j]++; } int cpot[T.m+1]; cpot[1]=1; for (int col=2; col<=M.m; col++) { cpot[col]=cpot[col-1]+array[col-1]; } for (int p=0; p<M.num; p++) { int col=M.data[p].j; int q=cpot[col]; T.data[q-1].i=M.data[p].j; T.data[q-1].j=M.data[p].i; T.data[q-1].data=M.data[p].data; cpot[col]++; } } return T; } int main() { TSMatrix M; M.m=2; M.n=3; M.num=4; M.data[0].i=1; M.data[0].j=2; M.data[0].data=1; M.data[1].i=2; M.data[1].j=2; M.data[1].data=3; M.data[2].i=3; M.data[2].j=1; M.data[2].data=6; M.data[3].i=3; M.data[3].j=2; M.data[3].data=5; TSMatrix T; T=fastTransposeMatrix(M, T); printf("使用改進方法:\n"); for (int i=0; i<T.num; i++) { printf("(%d,%d,%d)",T.data[i].i,T.data[i].j,T.data[i].data); } return 0; }
(1,3,6)(2,1,1)(2,2,3)(2,3,5) 這個演算法中含有四個並列的單迴圈,時間複雜度為
O(m+num)
(實際得到的是 O(2*m+2*num)
,當 m 和 num 足夠大時,可以省略常數引數),即使最壞情況下,矩陣中的元素都是非 0 元素,時間負責度為O(m*n)
。稱此演算法為快速轉置演算法。