稀疏矩阵基于“三元组”的转置算法实现
一、定义“三元组”结构
/**
* 三元组元素类
* @author wcqx64
*
*/
public class Triple {
//行标
private int row;
//列表
private int col;
//数值
private int date;
public Triple() {
super();
}
public Triple(int row, int col, int date) {
super();
this.row = row;
this.col = col;
this.date = date;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
}
import java.util.ArrayList;
import java.util.List;
/**
* 三元组结构
* @author wcqx64
*
*/
public class TSMatrix {
//非零元素 位置与数值信息列表
List<Triple> tripleList=new ArrayList<>();
//矩阵行数
int row_num;
//矩阵列数
int col_num;
//非零元素个数
int count;
//构造函数
public TSMatrix(List<Triple> tripleList, int row_num, int col_num, int count) {
super();
this.tripleList = tripleList;
this.row_num = row_num;
this.col_num = col_num;
this.count = count;
}
public TSMatrix() {
super();
}
//getter与setter方法
public int getRow_num() {
return row_num;
}
public List<Triple> getTripleList() {
return tripleList;
}
public void setTripleList(List<Triple> tripleList) {
this.tripleList = tripleList;
}
public void setRow_num(int row_num) {
this.row_num = row_num;
}
public int getCol_num() {
return col_num;
}
public void setCol_num(int col_num) {
this.col_num = col_num;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
二、转置操作实现类
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TransitionMatrix {
/**
* 初始化矩阵三元组结构
*
* @param a
* @return
*/
public static TSMatrix createSMatrix(int a[][]) {
// 定义三元组
TSMatrix tsmatrix = new TSMatrix();
List<Triple> tripleList = new ArrayList<>();
// 三元组初始化
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] != 0) {
Triple triple = new Triple();
triple.setRow(i);
triple.setCol(j);
triple.setDate(a[i][j]);
tripleList.add(triple);
}
}
}
// 初始化行
tsmatrix.setRow_num(a.length);
// 初始化列
tsmatrix.setCol_num(a[1].length);
// 非零元素个数
tsmatrix.setCount(tripleList.size());
tsmatrix.setTripleList(tripleList);
return tsmatrix;
}
/**
* 基于三元组存储的矩阵“普通转置算法”
* 利用三元组转换矩阵 三步: 1、将矩阵行列值互换 2、将每个三元组中行列互调换
* 3、重排三元组之间的次序实现矩阵转置 思想:按照原有矩阵的列序进行转置。即扫描pre_Transposition三元组 进行转置.
* 时间复杂度:O(col_num*count)矩阵列数与非零元素个数的乘积
*
* @param tsmatrix
* @return
*/
public static TSMatrix transposeSMtrix(TSMatrix pre_Transposition) {
// 转置前三元组列表
List<Triple> pre_tripleList = new ArrayList<>();
// 转置前三元组对象
pre_tripleList = pre_Transposition.getTripleList();
// 转置后三元组列表
List<Triple> post_tripleList = new ArrayList<>();
// 转置后三元组对象
TSMatrix post_Transposition = null;
// 按照原有矩阵列进行遍历
for (int i = 0; i < pre_Transposition.getCol_num(); i++) {
// 扫描pre_Transposition三元组
// 2、将每个三元组中行列互调换
// 3、重排三元组之间的次序实现矩阵转置
for (int j = 0; j < pre_Transposition.getCount(); j++) {
if (pre_tripleList.get(j).getCol() == i) {
//实现转置
Triple triple = new Triple(i, pre_tripleList.get(j).getRow(), pre_tripleList.get(j).getDate());
post_tripleList.add(triple);
}
}
}
// 1、矩阵行列数交换
post_Transposition = new TSMatrix(post_tripleList, pre_Transposition.getCol_num(),
pre_Transposition.getRow_num(), pre_Transposition.getCount());
return post_Transposition;
}
/**
* 基于三元组存储的矩阵“快速转置算法”
* 思想: 假设:在实现转置之前,已经确定原有矩阵每一列的第一个非零元素在转置后矩阵三元组的位置,
* 那么在遍历原有矩阵三元组便可得到转置后矩阵的三元组。将大大虽短时间复杂度。
* 因此在进行转置之前,需要先确定原有矩阵每列非零元素的个数和每列第一个非零元素在转置后矩阵三元组的位置。
* 设:cpot[col]为原有矩阵第col列第一个非零元素在转置后三元组的位置; num[col] 为原有矩阵第col列中非零元素的个数;
* 则一定满足: cpot[1]=1; cpot[col]=cpot[col-1]+num[col-1];
*
* @return
*/
public static TSMatrix fastTransposeSMtrix(TSMatrix pre_Transposition) {
// 转置前三元组列表
List<Triple> pre_tripleList = new ArrayList<>();
// 转置前三元组对象
pre_tripleList = pre_Transposition.getTripleList();
// 转置后三元组列表
List<Triple> post_tripleList = new ArrayList<>();
Triple[] mild=new Triple[pre_tripleList.size()];
// 转置后三元组对象
TSMatrix post_Transposition = null;
// 确定copt[]与num[]
int copt[] = new int[pre_Transposition.getCol_num()];
copt[0] = 1;
int num[] = new int[pre_Transposition.getCol_num()];
// 确定每列非零元素的个数
for (int i = 0; i < pre_Transposition.getCount(); i++) {
num[pre_tripleList.get(i).getCol()]++;
}
// 确定每列第一个非零元素在转置后三元组中的位置
for (int i = 1; i < copt.length; i++) {
copt[i] = copt[i - 1] + num[i - 1];
}
Triple triple = new Triple();
for (int i = 0; i < pre_Transposition.getCount(); i++) {
triple = pre_Transposition.getTripleList().get(i);
//获得遍历的三元组元素在转置后三元组的位置
int index = copt[triple.getCol()]-1;
mild[index]=new Triple(triple.getCol(), triple.getRow(), triple.getDate());
//下一个位置
copt[triple.getCol()]++;
}
Collections.addAll(post_tripleList, mild);
post_Transposition = new TSMatrix(post_tripleList, pre_Transposition.getCol_num(),
pre_Transposition.getRow_num(), pre_Transposition.getCount());
return post_Transposition;
}
/**
* 打印三元组
*
* @param tsmatrix
*/
public static void display(TSMatrix tsmatrix) {
// 转换前三元组
List<Triple> tripleList = tsmatrix.getTripleList();
System.out.print("row ");
System.out.print("col ");
System.out.println("value ");
for (int i = 0; i < tripleList.size(); i++) {
System.out.print(tripleList.get(i).getRow() + " ");
System.out.print(tripleList.get(i).getCol() + " ");
System.out.println(tripleList.get(i).getDate() + " ");
}
}
}
三、测试类
public class SMtest {
public static void main(String[] args) {
int a[][] = { { 0, 12, 9, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 3, 0, 0, 0, 0, 14, 0 },
{ 0, 0, 24, 0, 0, 0, 0 }, { 0, 18, 0, 0, 0, 0, 0 }, { 15, 0, 0, 7, 0, 0, 0 } };
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
System.out.print(a[i][j]+" ");
}
System.out.println();
}
// 初始化矩阵 三元组
System.out.println("初始化矩阵 三元组");
TSMatrix tsmatrix_original = TransitionMatrix.createSMatrix(a);
TransitionMatrix.display(tsmatrix_original);
// 基于三元组存储的矩阵“普通转置算法”
System.out.println("基于三元组存储的矩阵“普通转置算法”");
TSMatrix post_Transposition1 = TransitionMatrix.transposeSMtrix(tsmatrix_original);
TransitionMatrix.display(post_Transposition1);
//基于三元组存储的矩阵“快速转置算法”
System.out.println("基于三元组存储的矩阵“快速转置算法” ");
TSMatrix post_Transposition2=TransitionMatrix.fastTransposeSMtrix(tsmatrix_original);
TransitionMatrix.display(post_Transposition2);
}
}
四、测试结果
0 12 9 0 0 0 0
0 0 0 0 0 0 0
3 0 0 0 0 14 0
0 0 24 0 0 0 0
0 18 0 0 0 0 0
15 0 0 7 0 0 0
初始化矩阵 三元组
row col value
0 1 12
0 2 9
2 0 3
2 5 14
3 2 24
4 1 18
5 0 15
5 3 7
基于三元组存储的矩阵“普通转置算法”
row col value
0 2 3
0 5 15
1 0 12
1 4 18
2 0 9
2 3 24
3 5 7
5 2 14
基于三元组存储的矩阵“快速转置算法”
row col value
0 2 3
0 5 15
1 0 12
1 4 18
2 0 9
2 3 24
3 5 7
5 2 14