If you think about it, it will find that if the non-zero element node does not indicate the location of the location, then do the addition and multiplication, in order to determine the position of the node, each time you have multiple linked lists. Therefore, this domain is necessary for operational efficiency. In order to see the difference between the cross-linked list and single-link, I am derived from a single-link list, which requires a new structure first, as follows:
Class Matnode
{
PUBLIC:
Int data;
Int row, col;
Union {node
}
In addition, since such a trip table is split by a plurality of single-chain tables, in order to access the protection member of each single-chain list, you must declare the cross-chain table as a single-stranded watch class. That is, add Friend Class Matrix to the Class List declaration;
Definition and implementation of sparse matrices
#ifndef matrix_h
#define matrix_h
#include "list.h"
Class Matnode
{
PUBLIC:
Int data;
Int row, col;
Union {node
Matnode (int value = 0, node
: Data (Value), Down (P), ROW (i), Col (J) {}
Friend Ostream & Operator << (Ostream & Strm, Matnode & MTN)
{
STRM << '(' << mtn.row << ',' << mtn.col << ')' << mtn.data;
Return Strm;
}
}
Class Matrix: List
{
PUBLIC:
Matrix (): row (0), col (0), NUM (0) {}
Matrix (int Row, Int Col, Int Num): Row (Row), Col (Col), Num (NUM) {}
~ Matrix () {makeempty ();
void makeempty ()
{
List
While (first-> data.downrow! = null)
{
Q = first-> data.down;
First-> data.downrow = q-> first-> data.down;
Delete q;
}
List
ROW = COL = Num = 0;
}
Void input ()
{
IF (! row) {cout << "Input Matron Row:"; CIN >> ROW;
IF (! COL) {cout << "Input Matrix Column:"; CIN >> COL;
IF (! Num) {cout << "Enter a non-zero number:"; cin >> Num;}
IF (! Row ||! col ||! Num) Return;
Cout << Endl << "Please enter each non-zero element in order, primarily, input 0 means this end" << endl; int i, j, k, v; // i line number J column number K non-zero Valve non-zero value
Node
List
For (J = 1; J <= COL; J ) LastInsert (Matnode (0, NULL, 0, J));
For (i = 1; i <= row; i )
{
Q = new list
Q-> first-> data.row = i;
P-> Data.DownRow = Q;
P = Q-> first;
}
J = 1; Q = first-> data.downrow; first (); t = pnext ();
For (k = 0; k { IF (j> col) Break; COUT << Endl << "Enter" << j << "column non-zero element" << ENDL; COUT << "Number of lines:"; cin >> i; IF (i <1 || I> row) {J ; k -; q = first-> data.downrow; t = pnext (); continued;} Cout << "" non-zero element value "; cin >> V; IF (! v) {k -; company; Matnode Matnode (V, NULL, I, J); P = new node T-> data.down = p; t = p; While (Q-> first-> data.row! = i) q = q-> first-> data.down; Q-> LastInsert (T); } } Void print () { List Cout << Endl; While (q! = null) { Cout << * q; Q = Q-> first-> data.downrow; } } Matrix & Add (MATRIX & MATB) { // Initialization assignment auxiliary variable IF (Row! = Matb.Row || col! = matb.col || matb.num == 0) Return * this; Node Node Node List For (int J = 1; j <= col; j ) { PAT [J] = PNEXT (); PBT [J] = Matb.pnext (); } //Start For (int i = 1; i <= row; i ) { QA-> first (); QB-> first (); PA = QA-> pnext (); PB = QB-> pnext (); While (Pa! = null && pb! = null) { IF (PA-> DATA.COL == Pb-> Data.col) { PA-> DATA.DATA = Pb-> Data.Data; PBT [PB-> DATA.COL] -> DATA.DOWN = PB-> DATA.DOWN; QB-> Remove (); IF (! PA-> Data.Data) { PAT [PA-> DATA.COL] -> Data.Down = PA-> Data.Down; Qa-> remove (); } Else { PAT [PA-> DATA.col] = Pa; Qa-> pnext (); } } Else { IF (PA-> DATA.COL> PB-> DATA.COL) { PBT [PB-> DATA.COL] -> Data.Down = PB-> Data.Down; QB-> premove (); PB-> DATA.DOWN = PAT [PB-> Data.col] -> Data.Down; PAT [PB-> DATA.col] -> Data.Down = Pb; PAT [PB-> DATA.col] = Pb; QA-> INSERTBEFORE (PB); } Else IF (PA-> Data.col { PAT [PA-> DATA.col] = Pa; Qa-> pnext (); } } PA = QA-> Pget (); PB = QB-> Pget (); } IF (pa == null && pb! = null) { QA-> PgetPrior () -> link = Pb; QB-> PgetPrior () -> link = null; While (PB! = NULL) { PBT [PB-> DATA.COL] -> Data.Down = PB-> Data.Down; PB-> DATA.DOWN = PAT [PB-> Data.col] -> Data.Down; PAT [PB-> DATA.col] -> Data.Down = Pb; PAT [PB-> DATA.col] = Pb; PB = PB-> LINK; } } IF (pa! = null) { While (qa-> pget ()! = null) { PAT [PA-> DATA.col] = Pa; Qa-> pnext (); } } Qa = QA-> first-> data.downrow; QB = QB-> first-> data.downrow;} DELETE [] PAT; delete [] PBT; RETURN * THIS; } Private: Int row, col, num; } #ENDIF [Description] For the crosslink, just remember the operation of each node, you should consider its two normals, then the understanding of the various algorithms is not difficult. For example, the matrix plus method, "two matrix adds and two one-yuan polynomials are different, and the difference is that only one yuan polynomial has one change (index), and each non-zero element in the matrix has two arguments ( Value and column values), each node is in a list in the list, causing the modification of the pointer when inserting and deleting nodes, and requires more auxiliary pointers. "(" Data Structure (C language) ") In fact, private's row can be placed in the head node of the first line, but in order to clearly (it is chaotic), I will stand it out. In addition, many local considers are not very week, if you don't use it, it will be mistaken. [Post ", in order to say, the crosslink should not be a linear chain structure, according to the original book, put it in the chapter this chapter is not very appropriate;" Data structure (C language version) "put it and the generalized table in a chapter or reasonable. In fact, the cross chain table is not very difficult, it is very annoying; and, if not numeric operations, basically rarely used matrices, even if the matrix operation is used, in the matrix size, it can be replaced with a tip table with a two-dimensional array. From the perspective of the previous examination, this section has little questions, the reason is to trouble (you write trouble, he is brought together), not often used, the algorithm is fixed. So, if you are trouble, this part can also be skipped.