目录
前置数据结构定义
顺序表
template <class T> class arrayList
: public linearList< T >
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <exception>
#include <algorithm>
#include <iterator>
#include <type_traits>
#include <cstdint>
#include <cstddef>
#include <assert.h>
template<typename T> class arrayList;
template <typename value_type>
bool operator<( const arrayList<value_type>& lhs,
const arrayList<value_type>& rhs){
register int i;
for(i = 0; i < std::min( lhs.listSize, rhs.listSize ); ++i)
if( !( *( lhs.elements + i ) == *(rhs.elements + i) ) )
return *( lhs.elements + i) < *(rhs.elements + i);
return lhs.listSize < rhs.listSize;
}
template <typename value_type>
bool operator==( const arrayList<value_type>& lhs,
const arrayList<value_type>& rhs){
if( !( lhs.listSize == rhs.listSize ) ) return false;
register int i;
for(i = 0; i < lhs.listSize; ++i)
if( !( *( lhs.elements + i ) == *(rhs.elements + i) ) )
return false;
return true;
}
template <typename value_type>
bool operator!=( const arrayList<value_type>& lhs,
const arrayList<value_type>& rhs){
return !( lhs == rhs );
}
template < typename T >
std::ostream& operator<<( std::ostream& os, const arrayList< T >& x){
x.output( os );
return os;
}
template < class T > class linearList{
public:
virtual ~linearList( void ) {};
virtual bool empty( void ) const = 0;
virtual std::size_t size( void ) const = 0;
virtual T& get( int theIndex ) const = 0;
virtual int indexOf( const T& theElement ) const = 0;
virtual void erase( int theIndex ) = 0;
virtual void insert( int theIndex, const T& theElement ) = 0;
virtual void output( std::ostream& os ) const = 0;
};
template <class T> class arrayList
: public linearList< T >{
friend bool operator==<T>( const arrayList<T>&,
const arrayList<T>&);
friend bool operator< <T>( const arrayList<T>&,
const arrayList<T>&);
friend bool operator!=<T>( const arrayList<T>&,
const arrayList<T>&);
friend std::ostream& operator<< <T>( std::ostream&,
const arrayList<T>&);
class iterator{
public:
typedef std::bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef value_type* pointer;
typedef value_type& reference;
iterator(pointer thePosition = nullptr) : position( thePosition ) {}
reference operator*( void ) const { return *position; }
pointer operator->( void ) const { return &(*position); }
iterator& operator++( void ) {
++position;
return *this;
}
iterator& operator--( void ){
--position;
return *this;
}
iterator operator++( int dummy ){
iterator tmp = *this;
++position;
return tmp;
}
iterator operator--( int dummy ){
iterator tmp = *this;
--position;
return tmp;
}
bool operator!=( const iterator rhs ) const{
return position != rhs.position;
}
bool operator==( const iterator rhs ) const{
return position == rhs.position;
}
protected:
pointer position;
};
public:
arrayList(int initialCapacity = 10, std::size_t Scaler = 2);
arrayList( const arrayList< T >&);
~arrayList( void ){
if(elements) delete[]elements;
elements = nullptr;
}
virtual bool empty( void ) const { return listSize == 0; }
virtual std::size_t size( void ) const { return listSize; }
virtual T& get( int theIndex ) const;
virtual int indexOf( const T& theElement ) const;
virtual void erase( int theIndex );
virtual void insert( int theIndex, const T& theElement );
virtual void output( std::ostream& os ) const;
T& operator[]( std::size_t position ) const;
std::size_t capacity( void ) const { return arrayLength; }
iterator begin( void ){ return iterator( elements ); }
iterator end( void ){ return iterator( elements + listSize ); }
inline void trimToSize( void );
void setSize( std::size_t _Size );
protected:
void checkIndex(int theIndex) const;
T* elements { nullptr };
std::size_t arrayLength { 10 };
std::size_t listSize { 0 };
uint8_t Scaler;
};
template < class T >
void arrayList< T >::checkIndex( int theIndex ) const{
if( theIndex < 0 || theIndex >= listSize ){
std::ostringstream oss;
char buf[ 64 ];
sprintf( buf, "given index = %d; size = %d", theIndex, listSize );
oss << buf;
throw std::invalid_argument( oss.str() );
}
return;
}
template < class T >
arrayList< T >::arrayList(int initialCapacity, std::size_t Scaler)
:Scaler( Scaler ){
if( initialCapacity < 1 ){
std::ostringstream oss;
char buf[ 64 ];
sprintf( buf, "initial capacity = %d Must be > 0", initialCapacity);
oss << buf;
throw std::invalid_argument( oss.str() );
}
arrayLength = initialCapacity;
elements = new T[ arrayLength ];
}
template < class T >
inline void arrayList< T >::trimToSize( void ){
changeLength1D( elements, arrayLength, std::max( listSize, 1ULL ) );
arrayLength = std::max( listSize, 1ULL );
}
template <class T>
void arrayList< T >::setSize( std::size_t _Size ){
if( listSize > _Size )
for( std::ptrdiff_t i = _Size; i < listSize; ++i)
delete (elements + i);
listSize = _Size;
}
template <class T>
T& arrayList< T >::operator[]( std::size_t position ) const{
checkIndex( position );
return *(elements + position);
}
template < class T >
arrayList< T >::arrayList( const arrayList< T >& theList )
:arrayLength( theList.arrayLength )
,listSize( theList.listSize )
,elements( new T[ arrayLength ])
{
std::copy(theList.elements, theList.element + listSize, elements );
}
template < class T >
int arrayList< T >::indexOf( const T& theElement ) const{
int ret {};
return
( int )( ( ret =
std::find(elements, elements + listSize, theElement) - elements) )
== listSize ? -1 : ret;
}
template < typename T >
void arrayList< T >::erase(int theIndex ){
checkIndex( theIndex );
std::copy( elements + theIndex + 1, elements + listSize, elements + theIndex );
elements[ --listSize ].~T();
}
template < typename T >
void arrayList< T >::insert( int theIndex, const T& theElement ){
checkIndex( theIndex );
if(listSize == arrayLength ){
changeLength1D( elements, arrayLength, arrayLength * Scaler );
arrayLength *= Scaler;
}
std::copy_backward( elements + theIndex, elements + listSize, elements + listSize+1 );
elements[ theIndex ] = theElement;
}
template < typename T >
void arrayList< T >::output( std::ostream& os ) const{
std::copy( elements, elements + listSize, std::ostream_iterator< T >( os, "\t") );
}
template < typename value_type >
void changeLength1D( value_type*& pArray,
const signed long& N,
const signed long& M )
{
// static_assert(typename std::is_copy_constructible<value_type>::value, "requires copying");
if( nullptr == pArray )
throw std::domain_error( "array is nullptr" );
if( N < 0 || M < 0)
throw std::invalid_argument( "illegalParameterValue N|M given" );
std::size_t checkedN = static_cast< std::size_t >( N );
std::size_t checkedM = static_cast< std::size_t >( M );
value_type* temp = new value_type[ checkedM ];
std::copy( pArray, pArray + std::min( checkedN, checkedM ), temp );
delete [] pArray;
pArray = temp;
}
template < class T >
T& arrayList< T >::get( int theIndex ) const{
checkIndex( theIndex );
return elements[ theIndex ];
}
template < typename value_type, std::size_t formerN, std::size_t formerM >
value_type** chanegeLeagth2D( value_type (&_Matrix)[ formerN ][ formerM],
const signed long& newN,
const signed long& newM){
assert(newN > 0 && newM > 0 || "invalid argument nagetive N | M given");
// static_assert(typename std::is_copy_constructible<value_type>::value, "requires copying");
value_type ** _ScaledMatrix = new value_type*[ newN ];
for( std::ptrdiff_t i = 0; i < newM; ++i) _ScaledMatrix[ i ] = new value_type[ newM ];
int i,j;
std::size_t checkedN = static_cast< std::size_t >( newN );
std::size_t checkedM = static_cast< std::size_t >( newM );
for(i = 0; i < std::min( formerN, checkedN ); ++i)
for(j = 0; j < std::min( formerM, checkedM ); ++j)
_ScaledMatrix[i][j] = _Matrix[i][j];
return _ScaledMatrix;
}
template < typename InputIterator >
void myCopy(InputIterator begIt, InputIterator endIt, InputIterator resIt ){
while( !( begIt == endIt ) )
*resIt++ = *begIt++;
}
int main( void ){
int *pArray = new int[5] { 1, 2, 3, 4, 5 };
changeLength1D( pArray, 5L, 10L );
int i;
for(i = 0;i < 10;++i) std::clog << *( pArray + i ) << '\n';
constexpr int N { 5 };
int *pEnd = pArray + N;
for( std::ptrdiff_t i { N }; i > 0; --i )
std::clog << ( *( pEnd - i ) = i ) << '\t';
std::endl( std::cout );
return 0;
}
单链表
template < class T > class chain :
public linearList< T >;
#include <iostream>
#include <sstream>
#include <cstdio>
#include <iterator>
#include <type_traits>
template < class T > class linearList{
public:
virtual ~linearList( void ) {};
virtual bool empty( void ) const = 0;
virtual std::size_t size( void ) const = 0;
virtual T& get( int theIndex ) const = 0;
virtual int indexOf( const T& theElement ) const = 0;
virtual void erase( int theIndex ) = 0;
virtual void insert( int theIndex, const T& theElement ) = 0;
virtual void output( std::ostream& os ) const = 0;
};
template < class T > class extendedLinearList
: public linearList< T >
{
public:
virtual ~extendedLinearList( void ){ }
virtual void clear( void ) = 0;
virtual void push_back( const T& theElement ) = 0;
};
template < class T> struct chainNode{
T element;
chainNode< T > *next { nullptr };
chainNode( void ) {}
chainNode( const T& element )
:element( element )
{}
chainNode( const T& element, const chainNode< T > *next )
:chainNode( element )
{ this->next = next;}
};
template < typename T > class chain;
template < typename T >
std::ostream& operator<<( std::ostream& os, const chain< T >& x){
x.output( os );
return os;
}
template < class T > class chain : public linearList< T >{
class iterator{
public:
typedef std::forward_iterator_tag iterator_category;
typedef T value_type;
typedef chainNode< value_type >* pointer;
typedef chainNode< value_type >& reference;
iterator( pointer theNode = nullptr) : node( theNode ) {}
reference operator*( void ) const { return &node->element; }
pointer operator->( void ) const { return node->element; }
iterator& operator++( void ) {
node = node->next;
return *this;
}
iterator operator++( int dummy ){
iterator tmp = *this;
node = node->next;
return tmp;
}
bool operator!=( const iterator rhs ) const{
return node != rhs.node;
}
bool operator==( const iterator rhs ) const{
return node == rhs.node;
}
protected:
pointer node;
};
public:
chain( const chain< T >& );
~chain( void );
virtual bool empty( void ) const { return listSize == 0; }
virtual std::size_t size( void ) const { return listSize; }
virtual T& get( int theIndex ) const;
virtual int indexOf( const T& theElement ) const;
virtual void erase( int theIndex );
virtual void insert( int theIndex, const T& theElement );
virtual void output( std::ostream& os ) const;
iterator begin( void ){ return iterator( firstNode ); }
iterator end( void ){ return iterator(); }
protected:
void checkIndex( int theIndex ) const;
chainNode< T > *firstNode { nullptr };
std::size_t listSize { 0 };
};
template < class T >
chain< T >::chain( const chain< T >& theList)
:listSize( theList.listSize )
{
if( !listSize ) return;
chainNode< T > *sourceNode = theList.firstNode;
firstNode = new chainNode< T >( sourceNode->element );
chainNode< T > *targetNode = firstNode;
while( sourceNode ){
targetNode->next = new chainNode< T >( sourceNode->element );
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
}
template < class T >
void chain< T >::checkIndex( int theIndex ) const{
if( theIndex < 0 || theIndex >= listSize ){
std::ostringstream oss;
char buf[ 64 ];
sprintf( buf, "given index = %d; size = %d", theIndex, listSize );
oss << buf;
throw std::invalid_argument( oss.str() );
}
return;
}
template < class T >
T& chain< T >::get( int theIndex ) const{
checkIndex( theIndex );
chainNode< T > *currentNode = firstNode;
for( register int i { 0 }; i < theIndex; ++i)
currentNode = currentNode->next;
return currentNode->element;
}
template < class T >
int chain< T >::indexOf( const T& theElement ) const{
chainNode< T > *currentNode = firstNode;
int index = 0;
while( currentNode && !( currentNode->element == theElement ) ){
currentNode = currentNode->next;
++index;
}
return currentNode ? index : -1;
}
template < class T >
void chain< T >::erase( int theIndex ){
checkIndex( theIndex );
chainNode< T > *deleteNode;
if( !theIndex ){
deleteNode = firstNode;
firstNode = firstNode->next;
}else{
chainNode< T > *p =firstNode;
for( register int i { 0 }; i < theIndex; ++i )
p = p->next;
deleteNode = p->next;
p->next = p->next->next;
}
listSize--;
delete deleteNode;
}
template < class T >
void chain<T>::insert( int theIndex, const T& theElement ){
checkIndex( theIndex );
if( !theIndex ) firstNode = new chainNode< T >( theElement, firstNode );
else{
chainNode< T > *p = firstNode;
for( register int i { 0 }; i < theIndex; ++i )
p = p->next;
p->next = new chainNode< T >( theElement, p->next );
}
listSize++;
}
template < class T >
void chain< T >::output( std::ostream& os ) const{
for( chainNode< T > *currentNode = firstNode;
currentNode;
currentNode = currentNode->next)
os << currentNode->element << '\t';
}
int main( void ){
return 0;
}
矩阵元素三元组结构【稀疏矩阵】
// a term in sparseMatrix
#ifndef matrixTerm_
#define matrixTerm_
using namespace std;
template <class T>
struct matrixTerm
{
int row,
col;
T value;
operator T() const {return value;}
// type conversion from matrixTerm to T
};
#endif
矩阵链式元素结构 【十字链表】
// element types used by class linkedMatrix
#ifndef matrixElements_
#define matrixElements_
#include "extendedChain.h"
using namespace std;
template<class T>
struct rowElement
{
int col;
T value;
bool operator !=(const rowElement<T>& y)
{return (value != y.value);}
void output(ostream& out) const
{out << "column " << col
<< " value " << value << endl;}
};
template<class T>
ostream& operator<<(ostream& out, const rowElement<T>& x)
{x.output(out); return out;}
template<class T>
struct headerElement
{
int row;
extendedChain<rowElement<T> > rowChain;
bool operator !=(const headerElement<T>& y)
{return (row != y.row);}
void output(ostream& out) const
{out << "row " << row << endl << " " << rowChain << endl;}
};
template<class T>
ostream& operator<<(ostream& out,
const headerElement<T>& x)
{x.output(out); return out;}
#endif
稀疏矩阵
// sparse matrix using an extended array list
#ifndef sparseMatrix_
#define sparseMatrix_
#include <iostream>
#include "matrixTerm.h"
#include "extendedArrayList.h"
#include "myExceptions.h"
template<class T>
class sparseMatrix
{
friend ostream& operator<<
(ostream&, sparseMatrix<T>&);
friend istream& operator>>
(istream&, sparseMatrix<T>&);
public:
void transpose(sparseMatrix<T> &b);
void add(sparseMatrix<T> &b, sparseMatrix<T> &c);
private:
int rows, // number of rows in matrix
cols; // number of columns in matrix
arrayList<matrixTerm<T> > terms;
// list of nonzero terms
};
// overload <<
template <class T>
ostream& operator<<(ostream& out, sparseMatrix<T>& x)
{// Put x in output stream.
// put matrix characteristics
out << "rows = " << x.rows << " columns = "
<< x.cols << endl;
out << "nonzero terms = " << x.terms.size() << endl;
// put terms, one per line
for (arrayList<matrixTerm<T> >::iterator i = x.terms.begin();
i != x.terms.end(); i++)
out << "a(" << (*i).row << ',' << (*i).col
<< ") = " << (*i).value << endl;
return out;
}
// overload >>
template<class T>
istream& operator>>(istream& in, sparseMatrix<T>& x)
{// Input a sparse matrix.
// input matrix characteristics
int numberOfTerms;
cout << "Enter number of rows, columns, and #terms"
<< endl;
in >> x.rows >> x.cols >> numberOfTerms;
// set size of x.terms and ensure enough capacity
x.terms.reSet(numberOfTerms);
// input terms
matrixTerm<T> mTerm;
for (int i = 0; i < numberOfTerms; i++)
{
cout << "Enter row, column, and value of term "
<< (i + 1) << endl;
in >> mTerm.row >> mTerm.col >> mTerm.value;
x.terms.set(i, mTerm);
}
return in;
}
/****************************************************************/
// explict code tooverload with T = int for test as compiler
// unable to generate
// overload <<
ostream& operator<<(ostream& out, sparseMatrix<int>& x)
{// Put x in output stream.
// put matrix characteristics
out << "rows = " << x.rows << " columns = "
<< x.cols << endl;
out << "nonzero terms = " << x.terms.size() << endl;
// put terms, one per line
for (arrayList<matrixTerm<int> >::iterator i = x.terms.begin();
i != x.terms.end(); i++)
out << "a(" << (*i).row << ',' << (*i).col
<< ") = " << (*i).value << endl;
return out;
}
// overload >>
istream& operator>>(istream& in, sparseMatrix<int>& x)
{// Input a sparse matrix.
// input matrix characteristics
int numberOfTerms;
cout << "Enter number of rows, columns, and #terms"
<< endl;
in >> x.rows >> x.cols >> numberOfTerms;
// set size of x.terms and ensure enough capacity
x.terms.reSet(numberOfTerms);
// input terms
matrixTerm<int> mTerm;
for (int i = 0; i < numberOfTerms; i++)
{
cout << "Enter row, column, and value of term "
<< (i + 1) << endl;
in >> mTerm.row >> mTerm.col >> mTerm.value;
x.terms.set(i, mTerm);
}
return in;
}
/****************************************************************/
template<class T>
void sparseMatrix<T>::transpose(sparseMatrix<T> &b)
{// Return transpose of *this in b.
// set transpose characteristics
b.cols = rows;
b.rows = cols;
b.terms.reSet(terms.size());
// initialize to compute transpose
int* colSize = new int[cols + 1];
int* rowNext = new int[cols + 1];
// find number of entries in each column of *this
for (int i = 1; i <= cols; i++) // initialize
colSize[i] = 0;
for (arrayList<matrixTerm<T> >::iterator i = terms.begin();
i != terms.end(); i++)
colSize[(*i).col]++;
// find the starting point of each row of b
rowNext[1] = 0;
for (int i = 2; i <= cols; i++)
rowNext[i] = rowNext[i - 1] + colSize[i - 1];
// perform the transpose copying from *this to b
matrixTerm<T> mTerm;
for (arrayList<matrixTerm<T> >::iterator i = terms.begin();
i != terms.end(); i++)
{
int j = rowNext[(*i).col]++; // position in b
mTerm.row = (*i).col;
mTerm.col = (*i).row;
mTerm.value = (*i).value;
b.terms.set(j, mTerm);
}
}
template<class T>
void sparseMatrix<T>::add(sparseMatrix<T> &b, sparseMatrix<T> &c)
{// Compute c = (*this) + b.
// verify compatibility
if (rows != b.rows || cols != b.cols)
throw matrixSizeMismatch(); // incompatible matrices
// set characteristics of result c
c.rows = rows;
c.cols = cols;
c.terms.clear();
int cSize = 0;
// define iterators for *this and b
arrayList<matrixTerm<T> >::iterator it = terms.begin();
arrayList<matrixTerm<T> >::iterator ib = b.terms.begin();
arrayList<matrixTerm<T> >::iterator itEnd = terms.end();
arrayList<matrixTerm<T> >::iterator ibEnd = b.terms.end();
// move through *this and b adding like terms
while (it != itEnd && ib != ibEnd)
{
// row-major index plus cols of each term
int tIndex = (*it).row * cols + (*it).col;
int bIndex = (*ib).row * cols + (*ib).col;
if (tIndex < bIndex)
{// b term comes later
c.terms.insert(cSize++, *it);
it++;
}
else {if (tIndex == bIndex)
{// both in same position
// append to c only if sum not zero
if ((*it).value + (*ib).value != 0)
{
matrixTerm<T> mTerm;
mTerm.row = (*it).row;
mTerm.col = (*it).col;
mTerm.value = (*it).value + (*ib).value;
c.terms.insert(cSize++, mTerm);
}
it++;
ib++;
}
else
{// a term comes later
c.terms.insert(cSize++, *ib);
ib++;
}
}
}
// copy over remaining terms
for (; it != itEnd; it++)
c.terms.insert(cSize++, *it);
for (; ib != ibEnd; ib++)
c.terms.insert(cSize++, *ib);
}
#endif
十字矩阵
// linked representation of a sparse matrix
#ifndef linkedMatrix_
#define linkedMatrix_
#include <iostream>
#include "extendedChain.h"
#include "matrixElements.h"
using namespace std;
template<class T>
class linkedMatrix
{
friend ostream& operator<<
(ostream&, linkedMatrix<T>&);
friend istream& operator>>
(istream&, linkedMatrix<T>&);
public:
linkedMatrix(){}
~linkedMatrix(){}
void transpose(linkedMatrix<T> &b);
private:
int rows, // number of rows in matrix
cols; // number of columns in matrix
extendedChain<headerElement<T> > headerChain;
};
template<class T>
istream& operator>>(istream& in, linkedMatrix<T>& x)
{// Input matrix x from the stream in.
x.headerChain.clear();
// delete all nodes from x
// get matrix characteristics
int terms; // number of terms to be input
cout << "Enter number of rows, columns, and terms"
<< endl;
in >> x.rows >> x.cols >> terms;
// create fictional row zero
headerElement<T> header; // header for current row
header.row = 0; // current row number
// get terms of matrix x
for (int i = 1; i <= terms; i++)
{
// input next term
cout << "Enter row, column, and value of term "
<< i << endl;
rowElement<T> *term = new rowElement<T>;
int row;
in >> row >> term->col >> term->value;
// check if new term is part of current row
if (row > header.row)
{// start a new row
// append header of current row to
// header node chain only if row not zero
if (header.row != 0)
x.headerChain.push_back(header);
// prepare header for new row
header.row = row;
header.rowChain.zero();
// clear without deleting nodes
}
// add new term to row chain
header.rowChain.push_back(*term);
}
// take care of last row of matrix
if (header.row != 0)
x.headerChain.push_back(header);
header.rowChain.zero(); // save from chain destructor
return in;
}
template<class T>
ostream& operator<<(ostream& out, linkedMatrix<T>& x)
{// Put matrix x into the output stream out.
// output matrix dimensions
out << "rows = " << x.rows << " columns = "
<< x.cols << endl << " ";
if (x.headerChain.empty())
{
out << "No non-zero terms" << endl;
return out;
}
out << x.headerChain << endl;
return out;
}
/****************************************************************/
// explict code to overload with T = int for test as compiler
// unable to generate
istream& operator>>(istream& in, linkedMatrix<int>& x)
{// Input matrix x from the stream in.
x.headerChain.clear();
// delete all nodes from x
// get matrix characteristics
int terms; // number of terms to be input
cout << "Enter number of rows, columns, and terms"
<< endl;
in >> x.rows >> x.cols >> terms;
// create fictional row zero
headerElement<int> header; // header for current row
header.row = 0; // current row number
// get terms of matrix x
for (int i = 1; i <= terms; i++)
{
// input next term
cout << "Enter row, column, and value of term "
<< i << endl;
rowElement<int> *term = new rowElement<int>;
int row;
in >> row >> term->col >> term->value;
// check if new term is part of current row
if (row > header.row)
{// start a new row
// append header of current row to
// header node chain only if row not zero
if (header.row != 0)
x.headerChain.push_back(header);
// prepare header for new row
header.row = row;
header.rowChain.zero();
// clear without deleting nodes
}
// add new term to row chain
header.rowChain.push_back(*term);
}
// take care of last row of matrix
if (header.row != 0)
x.headerChain.push_back(header);
header.rowChain.zero(); // save from chain destructor
return in;
}
ostream& operator<<(ostream& out, linkedMatrix<int>& x)
{// Put matrix x into the output stream out.
// output matrix dimensions
out << "rows = " << x.rows << " columns = "
<< x.cols << endl << " ";
if (x.headerChain.empty())
{
out << "No non-zero terms" << endl;
return out;
}
out << x.headerChain << endl;
return out;
}
/****************************************************************/
template<class T>
void linkedMatrix<T>::transpose(linkedMatrix<T> &b)
{// Return transpose of *this as matrix b.
b.headerChain.clear(); // delete all nodes from b
// create bins to collect rows of b
extendedChain<rowElement<T> > *bin;
bin = new extendedChain<rowElement<T> > [cols + 1];
// head node iterator
extendedChain<headerElement<T> >::iterator
ih = headerChain.begin(),
ihEnd = headerChain.end();
// copy terms of *this into bins
while (ih != ihEnd)
{// examine all rows
int r = ih->row; // row number for row chain
// row chain iterator
extendedChain<rowElement<T> >::iterator
ir = ih->rowChain.begin(),
irEnd = ih->rowChain.end();
rowElement<T> x;
// terms from row r of *this go to column r of b
x.col = r;
while (ir != irEnd)
{// copy a term from the row chain into a bin
x.value = ir->value;
// x will eventually be in row ir->col of transpose
bin[ir->col].push_back(x);
ir++; // next term in row
}
ih++; // go to next row
}
// set dimensions of transpose
b.rows = cols;
b.cols = rows;
// assemble header chain of transpose
headerElement<T> h;
// scan bins
for (int i = 1; i <= cols; i++)
if (!bin[i].empty())
{// row i of transpose
h.row = i;
h.rowChain = bin[i];
b.headerChain.push_back(h);
bin[i].zero(); // save from destructor
}
h.rowChain.zero(); // save from destructor
delete [] bin;
}
#endif
下三角矩阵
// lower triangle matrix
#ifndef lowerTriangularMatrix_
#define lowerTriangularMatrix_
#include "myExceptions.h"
using namespace std;
template<class T>
class lowerTriangularMatrix
{
public:
lowerTriangularMatrix(int theN = 10);
~lowerTriangularMatrix() {delete [] element;}
T get(int, int) const;
void set(int, int, const T&);
private:
int n; // matrix dimension
T *element; // 1D array for lower triangle
};
template<class T>
lowerTriangularMatrix<T>::lowerTriangularMatrix(int theN)
{// Constructor.
// validate theN
if (theN < 1)
throw illegalParameterValue("Matrix size must be > 0");
n = theN;
element = new T [n * (n + 1) / 2];
}
template <class T>
T lowerTriangularMatrix<T>::get(int i, int j) const
{// Return (i,j)th element of matrix.
// validate i and j
if ( i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
// (i,j) in lower triangle iff i >= j
if (i >= j)
return element[i * (i - 1) / 2 + j - 1];
else
return 0;
}
template<class T>
void lowerTriangularMatrix<T>::set(int i, int j, const T& newValue)
{// Store newValue as (i,j)th element.
// validate i and j
if ( i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
// (i,j) in lower triangle iff i >= j
if (i >= j)
element[i * (i - 1) / 2 + j - 1] = newValue;
else
if (newValue != 0)
throw illegalParameterValue
("elements not in lower triangle must be zero");
}
#endif
三对角矩阵
// tridiagonal matrix
#ifndef tridiagonal_
#define tridiagonal_
#include "myExceptions.h"
using namespace std;
template<class T>
class tridiagonalMatrix
{
public:
tridiagonalMatrix(int theN = 10);
~tridiagonalMatrix() {delete [] element;}
T get(int, int) const;
void set(int, int, const T&);
private:
int n; // matrix dimension
T *element; // 1D array for tridiagonal
};
template<class T>
tridiagonalMatrix<T>::tridiagonalMatrix(int theN)
{// Constructor.
// validate theN
if (theN < 1)
throw illegalParameterValue("Matrix size must be > 0");
n = theN;
element = new T [3 * n - 2];
}
template <class T>
T tridiagonalMatrix<T>::get(int i, int j) const
{// Return (i,j)th element of matrix.
// validate i and j
if ( i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
// determine lement to return
switch (i - j)
{
case 1: // lower diagonal
return element[i - 2];
case 0: // main diagonal
return element[n + i - 2];
case -1: // upper diagonal
return element[2 * n + i - 2];
default: return 0;
}
}
template<class T>
void tridiagonalMatrix<T>::set(int i, int j, const T& newValue)
{// Store newValue as (i,j)th element
// validate i and j
if ( i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
switch (i - j)
{
case 1: // lower diagonal
element[i - 2] = newValue; break;
case 0: // main diagonal
element[n + i - 2] = newValue; break;
case -1: // upper diagonal
element[2 * n + i - 2] = newValue; break;
default: if (newValue != 0)
throw illegalParameterValue
("non-tridiagonal elements must be zero");
}
}
#endif
对角矩阵
// diagonal matrix
#ifndef diagonalMatrix_
#define diagonalMatrix_
#include "myExceptions.h"
using namespace std;
template<class T>
class diagonalMatrix
{
public:
diagonalMatrix(int theN = 10);
~diagonalMatrix() {delete [] element;}
T get(int, int) const;
void set(int, int, const T&);
private:
int n; // matrix dimension
T *element; // 1D array for diagonal elements
};
template<class T>
diagonalMatrix<T>::diagonalMatrix(int theN)
{// Constructor.
// validate theN
if (theN < 1)
throw illegalParameterValue("Matrix size must be > 0");
n = theN;
element = new T [n];
}
template <class T>
T diagonalMatrix<T>::get(int i, int j) const
{// Return (i,j)th element of matrix.
// validate i and j
if (i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
if (i == j)
return element[i-1]; // diagonal element
else
return 0; // nondiagonal element
}
template<class T>
void diagonalMatrix<T>::set(int i, int j, const T& newValue)
{// Store newValue as (i,j)th element.
// validate i and j
if (i < 1 || j < 1 || i > n || j > n)
throw matrixIndexOutOfBounds();
if (i == j)
// save the diagonal value
element[i-1] = newValue;
else
// nondiagonal value, newValue must be zero
if (newValue != 0)
throw illegalParameterValue
("nondiagonal elements must be zero");
}
#endif