1 sparse matrix:
Assuming m * n matrix, there is no element t 0. Let q = t / (m * n), q is called a sparse matrix factor. Generally considered q <= 0.05 when considered sparse matrix.
2 triple order table
If storage space is allocated to each element, then the matrix contains a large number of 0 will result in waste of resources. So in general we store a compressed manner, except that the stored value of non-zero elements, but also store the corresponding row and column. Thus, the sparse matrix may be represented by non-zero elements and triples the number of ranks is determined uniquely.
Related defined as follows:
typedef int the Status #define MAX_ROW 100 #define MAX_SIZE 101 typedef int elemType; typedef struct { int Row; // set the row index int COL; // set the column index value elemtype value; // set the element value } Triple; typedef struct { int RN; // set the number of rows int CN; // set the number of columns int TN; Triple Data [MAX_SIZE]; // set array } TMatrix;
Transpose operation (transpose performed in a certain order):
Here we note that storage is stored in rows.
The time complexity is rn * tn. Tn when much smaller than rn * cn use, otherwise the big time complexity compared to traditional methods and more. (Sacrifice time to optimize storage)
//转置操作 void TransposeSMatrix(TMatrix M, TMatrix T) { T.rn = M.cn; T.cn = M.rn; T.tn = M.tn; if (T.tn) { q = 1; for (col = 1; col < M.rn; ++col) for (p = 1; p < M.tn; ++p) if (M.data[p].cn == col) { T.data[q].rn = M.data[p].cn; T.data[q].cn = M.data[p].rn; T.data[q].value = M.data[p].value; } } }
Quick transpose:
// quick transposition void FastTranspodeSMtrix (M TMatrix, TMatrix T) { T.rn = m.cn; t.cn = M.rn; T.tn = M.tn; IF (T.tn) { for (COL = . 1 ; COL <M.rn; ++ COL) NUM [COL] = 0 ; for (T = . 1 ; T <= T M.tnl ++) ++ NUM [M.data [T] .cn]; the cPOT [ 1 ] = 1 ; // find the first one of the first non-zero row col element M.data sequence number for (col = 2 ; col <= M.tn; P ++) the cPOT [col] = the cPOT [COL - . 1 ] + NUM [COL - . 1 ]; for (p=1; p <= M.tn; ++p) { col = M.data[p].cn; q = cpot[col]; T.data[q].rn = M.data[p].cn; T.data[q].cn = M.data[p].rn; T.data[q].value = M.data[p].value; ++cpot[col]; } } }
This algorithm compared to the previous over one of the two auxiliary vectors. There are two single cycle, the time complexity is rn + cn. Number of elements and the non-0 rn * cn same order of magnitude, the time complexity of the algorithm is the same as M of the classical.
3 row sequence table logical connection:
We indicating "line" assistant cpot fixed array of information storage structure among the sparse matrix.
The following two matrix multiplication algorithm:
typedef struct { Triple data[MAX_SIZE]; int rpos[MAX_ROW]; int rn, cn, tn; }RLSMatrix; //三元组定义 默认行从1开始 void MultsMatrix(PLSMatrix a, RLSMatrix b, RLSMatrix c) { elemtype ctemp[MAX_SIZE]; int p, q, arow, ccol, brow, t; if (a.cn != b.rn) { cout << "Error" << endl; } else { c.rn = a.rn; c.cn = b.cn; c.tn = 0; if (a.tn * b.tn != 0) { for(= AROW . 1 ; AROW <= a.rn; AROW ++) // for each row of a process { cTemp [AROW] = 0 ; // current line of each element of the accumulator cleared 0 c.rpos [AROW] = C. + TN . 1 ; P = a.rpos [AROW]; for (; P <a.rpos [arrow arrow + . 1 ]; P ++) // for each current row 0 yuan non { BROW = a.data [ P] .col; // find the row number corresponding to the b IF (BROW <b.rn) T = b.rpos [BROW + . 1 ]; the else T = + b.tn . 1; For (Q = b.rpos [BROW]; Q <T; ++ Q) { CCOL = b.data [Q] .col; cTemp [CCOL] + = a.data [P] * .Value b.data [Q] .Value; } } for (CCOL = . 1 ; CCOL <= c.cn; CCOL ++) // compression stored in the row non-0 yuan IF (cTemp [CCOL] =! 0 ) { IF (++ c.tn> MAX_SIZE) { COUT << " Error " << endl; exit(0); } else c.data[c.tn] = (arow, ccol, ctemp[ccol]); } } } } }
4 Cross List
When the non-zero matrix IE number and position change during operation is large, it should not be used to represent the sequence structure of linear form triples. For example, the matrix B is added to the matrix A, since the operation of non-zero elements of the array causes a change. Therefore, the use of chain table easier.
In addition to the row and column values, and two pointers, the identifier for a peer of the next non-zero element and the same row of non-0.
typedef struct clnode { int I, J; elemType E; struct clnode Down *, * right; } OLNode; // below are definitions of the entire sparse matrix typedef struct { int MU; int NU; int TU; OLNode * rhead; OLNode * chead; } CrossList; void CreateSMatrix_OL (CressList & m) { int m, n-, T; // create a sparse matrix. Cross chain represented using IF (M) Free (M); COUT <<" Please enter the number of rows of the matrix M, the number of columns and the number of non-0 element ' << endl; CIN >> >> m >> n- T; M.mu = m; = n-M.nu; M.tu = T; // number of rows uM amount, the number of columns and the number of nonzero elements IF (! (M.rhead = (OLNode *) the malloc ((m + . 1 ) * the sizeof (OLNode)))) COUT << " input data error " << endl; IF (! (M.chead = (OLNode *) the malloc ((n-+ . 1 ) * the sizeof (OLNode)))) COUT << " input data error " << endl; M. rhead [] = M.Permission [] =NULL; for (CIN I >> >> >> J E; I =! 0 ; CIN I >> >> >> J E;) { IF ! ((P = (OLNode *) the malloc ( the sizeof (OLNode)) )) COUT << " data allocation error " << endl; P -> I = I; p-> J = J; p-> E = E; // generating node IF (M.rhead [I] == || M.rhead NULL [I] -> J> J) {p-> right = M.rhead [I]; M.rhead [I] = P;} the else { // find the insertion position of the row in the table for (Q = M.rhead [I]; (Q-> right) && Q-> right-> J <J; Q = Q-> right); p->right = q->right; q->right =P; } IF (M.chead [J] == NULL || M.chead [J] -> I> I) {p-> Down = M.chead [J]; M.chead [J] = P; } the else { // find the insertion position in the list for (Q = M.chead [I]; (Q-> Down) && Q-> DOWN-> J <J; Q = Q-> Down); P - > = Q- Down> Down; Q-> Down = P; // complete insertion column } } }
5 General List
Generalized linear table is a generalization of the table.
Generally referred to as generalized list:
LS = (a1, a2, a3,..., an)
Each element may be a single element, the table may be generalized, and the sub-tables are called atoms generalized table.
When generalized list is not empty, we used to call the first element is the header, said the remaining elements for the end of the table (a2, a3, a4, ..., an).
It is worth recalling list () and (()) different. The former table is empty, a length of 0; 1 is a length which can be decomposed to obtain the header, footer table are empty ().
This flexibility will need to use a chain storage structure. Node needs two structures, one is the node atoms to atoms represented by flags field, the composition range; the other is a list by standard range, and range pointer field identification header components.
Seeking a generalized table depth (recursively):
Generalized maximum depth of the respective sub-table is the table plus a depth, a distinction length;
We atom with 0 ATOM (Tag), and vice versa for the child table.
typedef struct GLNode { ElemTag Tag; // common portion, for distinguishing atoms and Table nodes int Atom; GLNode * HP; GLNode * TP; } * a GList; // Solution Table depth int GListDepth (a GList L) { int DEP, max; a GList PP; // use head and tail linked list storage structure, the depth L out generalized table IF (L!) return . 1 ; // empty list a depth IF (L-> the ATOM Tag ==) retun 0 ; // atoms depth 0 for (max = 0, L = PP; PP; PP = PP-> TP) { DEP = GListDepth (pp-> hp); // seek to pp-> hp for the first sub-table pointers depth IF (DEP> max) max = DEP; } return max + . 1 ; }
2 recursive copy generalized table
Each recursive copy headers and footers:
// Copy generalized table void CopyGlist (a GList & T, a GList L) { IF (! L) T = NULL; // copy empty table the else { IF ((T = (a GList)! The malloc ( the sizeof (GLNode))) COUT < < " erroneous data distribution occurs " << endl; // build the table node T-> = L-Tag> Tag; IF (L-> Tag == 0 ) T-> = L-Atom> Atom; // copy single atom the else { CopyGlist (T -> HP, L-> HP); CopyGlist (T -> TP, L-> TP); } } }