您好,登錄后才能下訂單哦!
本文實例講述了Java數據結構之稀疏矩陣定義與用法。分享給大家供大家參考,具體如下:
稀疏矩陣非零元素的三元組類:
package com.clarck.datastructure.matrix; /** * 稀疏矩陣的壓縮存儲 * * 稀疏矩陣非零元素的三元組類 * * @author clarck * */ public class Triple implements Comparable<Triple> { // 行號,列號, 元素值,默認訪問權限 int row, colum, value; public Triple(int row, int colum, int value) { if (row < 0 || colum < 0) { throw new IllegalArgumentException("稀疏矩陣元素三元組的行/列序號非正數"); } this.row = row; this.colum = colum; this.value = value; } /** * 拷貝構造方法,復制一個三元組 * * @param elem */ public Triple(Triple elem) { this(elem.row, elem.colum, elem.value); } @Override public String toString() { return "(" + row + ", " + colum + ", " + value + ")"; } /** * 兩個三元組是否相等,比較位置和元素值 */ public boolean equals(Object obj) { if (!(obj instanceof Triple)) return false; Triple elem = (Triple) obj; return this.row == elem.row && this.colum == elem.colum && this.value == elem.value; } /** * 根據三元組位置比較兩個三元組的大小,與元素值無關,約定三元組排序次序 */ @Override public int compareTo(Triple elem) { //當前三元組對象小 if (this.row < elem.row || this.row == elem.row && this.colum < elem.colum) return -1; //相等,與equals方法含義不同 if (this.row == elem.row && this.colum == elem.colum) return 0; //當前三元組對象大 return 1; } /** * 加法, +=運算符作用 * @param term */ public void add(Triple term) { if (this.compareTo(term) == 0) this.value += term.value; else throw new IllegalArgumentException("兩項的指數不同,不能相加"); } /** * 約定刪除元素 * * @return */ public boolean removable() { //不存儲為0的元素 return this.value == 0; } /** * 返回對稱位置矩陣元素的三元組 * @return */ public Triple toSymmetry() { return new Triple(this.colum, this.row, this.value); } /** * 加法運算,重載運算符+ * @return */ public Triple plus(Triple term) { Triple tmp = new Triple(this); tmp.add(term); return tmp; } }
三元組順序存儲的稀疏矩陣類:
package com.clarck.datastructure.matrix; import com.clarck.datastructure.linear.SeqList; /** * 稀疏矩陣的壓縮存儲 * * 稀疏矩陣三元組順序表 * * 三元組順序存儲的稀疏矩陣類 * * @author clarck * */ public class SeqSparseMatrix { // 矩陣行數、列數 private int rows, columns; // 稀疏矩陣三元組順序表 private SeqList<Triple> list; /** * 構造rows行,colums列零矩陣 * * @param rows * @param columns */ public SeqSparseMatrix(int rows, int columns) { if (rows <= 0 || columns <= 0) throw new IllegalArgumentException("矩陣行數或列數為非正數"); this.rows = rows; this.columns = columns; // 構造空順序表,執行SeqList()構造方法 this.list = new SeqList<Triple>(); } public SeqSparseMatrix(int rows, int columns, Triple[] elems) { this(rows, columns); // 按行主序插入一個元素的三元組 for (int i = 0; i < elems.length; i++) this.set(elems[i]); } /** * 返回矩陣第i行第j列元素,排序順序表的順序查找算法,O(n) * * @param i * @param j * @return */ public int get(int i, int j) { if (i < 0 || i >= rows || j < 0 || j >= columns) throw new IndexOutOfBoundsException("矩陣元素的行或列序號越界"); Triple item = new Triple(i, j, 0); int k = 0; Triple elem = this.list.get(k); // 在排序順序表list中順序查找item對象 while (k < this.list.length() && item.compareTo(elem) >= 0) { // 只比較三元組元素位置,即elem.row == i && elem.column == j if (item.compareTo(elem) == 0) return elem.value; // 查找到(i, j), 返回矩陣元素 k++; elem = this.list.get(k); } return 0; } /** * 以三元組設置矩陣元素 * * @param elem */ public void set(Triple elem) { this.set(elem.row, elem.colum, elem.value); } /** * 設置矩陣第row行第column列的元素值為value,按行主序在排序順序表list中更改或插入一個元素的三元組, O(n) * * @param row * @param column * @param value */ public void set(int row, int column, int value) { // 不存儲值為0元素 if (value == 0) return; if (row >= this.rows || column >= this.columns) throw new IllegalArgumentException("三元組的行或列序號越界"); Triple elem = new Triple(row, column, value); int i = 0; // 在排序的三元組順序表中查找elem對象,或更改或插入 while (i < this.list.length()) { Triple item = this.list.get(i); // 若elem存在,則更改改位置矩陣元素 if (elem.compareTo(item) == 0) { // 設置順序表第i個元素為elem this.list.set(i, elem); return; } // elem 較大時向后走 if (elem.compareTo(item) >= 0) i++; else break; } this.list.insert(i, elem); } @Override public String toString() { String str = "三元組順序表:" + this.list.toString() + "\n"; str += "稀疏矩陣" + this.getClass().getSimpleName() + "(" + rows + " * " + columns + "): \n"; int k = 0; // 返回第k個元素,若k指定序號無效則返回null Triple elem = this.list.get(k++); for (int i = 0; i < this.rows; i++) { for (int j = 0; j < this.columns; j++) if (elem != null && i == elem.row && j == elem.colum) { str += String.format("%4d", elem.value); elem = this.list.get(k++); } else { str += String.format("%4d", 0); } str += "\n"; } return str; } /** * 返回當前矩陣與smat相加的矩陣, smatc=this+smat,不改變當前矩陣,算法同兩個多項式相加 * * @param smat * @return */ public SeqSparseMatrix plus(SeqSparseMatrix smat) { if (this.rows != smat.rows || this.columns != smat.columns) throw new IllegalArgumentException("兩個矩陣階數不同,不能相加"); // 構造rows*columns零矩陣 SeqSparseMatrix smatc = new SeqSparseMatrix(this.rows, this.columns); int i = 0, j = 0; // 分別遍歷兩個矩陣的順序表 while (i < this.list.length() && j < smat.list.length()) { Triple elema = this.list.get(i); Triple elemb = smat.list.get(j); // 若兩個三元組表示相同位置的矩陣元素,則對應元素值相加 if (elema.compareTo(elemb) == 0) { // 相加結果不為零,則新建元素 if (elema.value + elemb.value != 0) smatc.list.append(new Triple(elema.row, elema.colum, elema.value + elemb.value)); i++; j++; } else if (elema.compareTo(elemb) < 0) { // 將較小三元組復制添加到smatc順序表最后 // 復制elema元素執行Triple拷貝構造方法 smatc.list.append(new Triple(elema)); i++; } else { smatc.list.append(new Triple(elemb)); j++; } } // 將當前矩陣順序表的剩余三元組復制添加到smatc順序表最后 while (i < this.list.length()) smatc.list.append(new Triple(this.list.get(i++))); // 將smat中剩余三元組復制添加到smatc順序表最后 while (j < smatc.list.length()) { Triple elem = smat.list.get(j++); if (elem != null) { smatc.list.append(new Triple(elem)); } } return smatc; } /** * 當前矩陣與smat矩陣相加,this+=smat, 改變當前矩陣,算法同兩個多項式相加 * * @param smat */ public void add(SeqSparseMatrix smat) { if (this.rows != smat.rows || this.columns != smat.columns) throw new IllegalArgumentException("兩個矩陣階數不同,不能相加"); int i = 0, j = 0; // 將mat的各三元組依次插入(或相加)到當前矩陣三元組順序表中 while (i < this.list.length() && j < smat.list.length()) { Triple elema = this.list.get(i); Triple elemb = smat.list.get(j); // 若兩個三元組表示相同位置的矩陣元素,則對應元素值相加 if (elema.compareTo(elemb) == 0) { // 相加結果不為0,則新建元素 if (elema.value + elemb.value != 0) this.list.set(i++, new Triple(elema.row, elema.colum, elema.value + elemb.value)); else this.list.remove(i); j++; } else if (elema.compareTo(elemb) < 0) { // 繼續向后尋找elemb元素的插入元素 i++; } else { // 復制elemb元素插入作為this.list的第i個元素 this.list.insert(i++, new Triple(elemb)); j++; } } // 將mat中剩余三元組依次復制插入當前矩陣三元組順序表中 while (j < smat.list.length()) { this.list.append(new Triple(smat.list.get(j++))); } } // 深拷貝 public SeqSparseMatrix(SeqSparseMatrix smat) { this(smat.rows, smat.columns); // 創建空順序表,默認容量 this.list = new SeqList<Triple>(); // 復制smat中所有三元組對象 for (int i = 0; i < smat.list.length(); i++) this.list.append(new Triple(smat.list.get(i))); } /** * 比較兩個矩陣是否相等 */ public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof SeqSparseMatrix)) return false; SeqSparseMatrix smat = (SeqSparseMatrix) obj; return this.rows == smat.rows && this.columns == smat.columns && this.list.equals(smat.list); } /** * 返回轉置矩陣 * @return */ public SeqSparseMatrix transpose() { //構造零矩陣,指定行數和列數 SeqSparseMatrix trans = new SeqSparseMatrix(columns, rows); for (int i = 0; i < this.list.length(); i++) { //插入矩陣對稱位置元素的三元組 trans.set(this.list.get(i).toSymmetry()); } return trans; } }
測試類:
package com.clarck.datastructure.matrix; /** * 稀疏矩陣的壓縮存儲 * * 稀疏矩陣三元組順序表 * * 三元組順序表表示的稀疏矩陣及其加法運算 * * @author clarck * */ public class SeqSparseMatrix_test { public static void main(String args[]) { Triple[] elemsa = { new Triple(0, 2, 11), new Triple(0, 4, 17), new Triple(1, 1, 20), new Triple(3, 0, 19), new Triple(3, 5, 28), new Triple(4, 4, 50) }; SeqSparseMatrix smata = new SeqSparseMatrix(5, 6, elemsa); System.out.print("A " + smata.toString()); Triple[] elemsb = { new Triple(0, 2, -11), new Triple(0, 4, -17), new Triple(2, 3, 51), new Triple(3, 0, 10), new Triple(4, 5, 99), new Triple(1, 1, 0) }; SeqSparseMatrix smatb = new SeqSparseMatrix(5,6,elemsb); System.out.print("B " + smatb.toString()); SeqSparseMatrix smatc = smata.plus(smatb); System.out.print("C=A+B"+smatc.toString()); System.out.println(); smata.add(smatb); System.out.print("A+=B" + smata.toString()); System.out.println("C.equals(A)?" + smatc.equals(smata)); SeqSparseMatrix smatd = new SeqSparseMatrix(smatb); smatb.set(0,2,1); System.out.print("B " + smatb.toString()); System.out.print("D " + smatd.toString()); System.out.println("A轉置" + smata.transpose().toString()); } }
運行結果:
A 三元組順序表:((0, 2, 11), (0, 4, 17), (1, 1, 20), (3, 0, 19), (3, 5, 28), (4, 4, 50)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 11 0 17 0 0 20 0 0 0 0 0 0 0 0 0 0 19 0 0 0 0 28 0 0 0 0 50 0 B 三元組順序表:((0, 2, -11), (0, 4, -17), (2, 3, 51), (3, 0, 10), (4, 5, 99)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 -11 0 -17 0 0 0 0 0 0 0 0 0 0 51 0 0 10 0 0 0 0 0 0 0 0 0 0 99 C=A+B三元組順序表:((1, 1, 20), (2, 3, 51), (3, 0, 29), (3, 5, 28), (4, 4, 50), (4, 5, 99)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 51 0 0 29 0 0 0 0 28 0 0 0 0 50 99 A+=B三元組順序表:((1, 1, 20), (2, 3, 51), (3, 0, 29), (3, 5, 28), (4, 4, 50), (4, 5, 99)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 51 0 0 29 0 0 0 0 28 0 0 0 0 50 99 C.equals(A)?true B 三元組順序表:((0, 2, 1), (0, 4, -17), (2, 3, 51), (3, 0, 10), (4, 5, 99)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 1 0 -17 0 0 0 0 0 0 0 0 0 0 51 0 0 10 0 0 0 0 0 0 0 0 0 0 99 D 三元組順序表:((0, 2, -11), (0, 4, -17), (2, 3, 51), (3, 0, 10), (4, 5, 99)) 稀疏矩陣SeqSparseMatrix(5 * 6): 0 0 -11 0 -17 0 0 0 0 0 0 0 0 0 0 51 0 0 10 0 0 0 0 0 0 0 0 0 0 99 A轉置三元組順序表:((0, 3, 29), (1, 1, 20), (3, 2, 51), (4, 4, 50), (5, 3, 28), (5, 4, 99)) 稀疏矩陣SeqSparseMatrix(6 * 5): 0 0 0 29 0 0 20 0 0 0 0 0 0 0 0 0 0 51 0 0 0 0 0 0 50 0 0 0 28 99
更多關于java算法相關內容感興趣的讀者可查看本站專題:《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。