1 / 55

Chapter 4

Chapter 4. ARRAYS AND MATRICES. 4.1 ARRAYS. 数组是一种常用(熟悉)的数据结构。 线性表包括:数组和广义表。 4.4.1 The Abstract Data Type Each instance of the data object array is a set of pairs of the form (index, value). Example High = { (0,82), (1,79), (2,85), (3,92), (4,88), (5, 89), (6,91) }

makya
Télécharger la présentation

Chapter 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 4 ARRAYS AND MATRICES

  2. 4.1 ARRAYS • 数组是一种常用(熟悉)的数据结构。 • 线性表包括:数组和广义表。 4.4.1 The Abstract Data Type • Each instance of the data object array is a set of pairs of the form (index, value). Example High = { (0,82), (1,79), (2,85), (3,92), (4,88), (5, 89), (6,91) } • The functions performed: • Create – Creates an initially empty array • Store – Adds a pair of the form to the set. • Retrieve – Retrieves the value of the pair that has a given index.

  3. AbstractDataType Array { instances set of (index, value) pairs, no two pairs have the same index operations Create ( ): create an empty array Store (index,value ): add this pair to set deleting existing pair (if any) with the same index Retrieve (index ): return the pair with this index value } ADT 4.1 Abstract data type specification of an array

  4. 4.1.2 Indexing a C++ Array • The index (also called subscript) of an array in C++ must be of the form [i1][i2][i3] … [ik] int score [u1][u2][u3] … [uk] • (数组需要预留空间)The memory begins at byte start and extends up to and including byte start+size(score)-1

  5. 4.1.3 Row- and Column-Major Mappings • 数组的存储方式 • row major mapping (按行排列) • column major mapping (按列排列) • 访问元素位置: Start+map( i1,i2, i3, … ik )*sizeof(int)

  6. [0][0] [0][1] [0][2] [0][3] [0][4] [0][5] [1][0] [1][1] [1][2] [1][3] [1][4] [1][5] [2][0] [2][1] [2][2] [2][3] [2][4] [2][5] Figure 4.1 Tabular arrangement of indices for int score[3][6] 0 1 2 3 4 5 0 3 6 9 12 15 6 7 8 9 10 11 1 4 7 10 13 16 12 13 14 15 16 17 2 5 8 11 14 17 • Row-major mapping (b) Column-major mapping Figure 4.2 Mapping a two-dimensional array

  7. 4.1.4 the Class Array1D • 一维数组可以看成是一个线性表或向量,适合于随机查找。 • Although C++ support one dimensional arrays,this support is rather primitive. • Ex.: To declared an array int a[ 9 ] Accessing a[-3], a[90] are invalid indexes. • the array cannot be output using the statement cout << a << endl;

  8. template <class T> class Array1D { public : Array1D(int size = 0); Array1D(const Array1D<T>& v); //copy constructor ~Array1D( ) { delete [ ] element; } T& operator [ ](int i) const ; int Size( ) { return size; } Array1D<T>&operator = (const Array1D<T>&v); Array1D<T> operator + ( ) const; // unary + Array1D<T>operator + (const Array1D<T>& v) const; Array1D<T>operator - ( ) const; // unary minus Array1D<T>operator - (const Array1D<T>& v) const; Array1D<T>operator * (const Array1D<T>& v) const; Array1D<T>&operator += (const T& x); private: int size; T *element; // 1D array }; Program 4.1 A one-dimensional array class

  9. template <class T> Array1D<T>::Array1D(int sz) { // Constructor for one-dimensional arrays. if (sz < 0) throw BadInitializers(); size = sz; element = new T[sz]; } template <class T> Array1D<T>::Array1D(const Array1D<T>& v) { // Copy constructor for one-dimensional arrays. size = v.size; element = new T[size]; // get space for (int i = 0; i < size; i++) // copy elements element[i] = v.element[i]; } Program 4.2 Constructors for a one-dimensional array

  10. template <class T> T& Array1D<T>: :operator [ ] (int i) const { // Return reference to element i. if (i < 0 || i >= size) throw OutOfBounds( ); return element[i]; } Program 4.3 Overloading the array indexing operator template <class T> Array1D<T>& Array1D<T>: :operator = (const Array1D<T>& v) { // Overload assignment operator . if (this != &v) { // not self-assignment size = v.size; delete [ ] element; // free old space element = new T[size]; // get right amount for(int i = 0; i<size; i++) //copy elements element[i] = v.element[i]; } return *this ; } Program 4.4 Overloading the assignment operator

  11. template <class T> Array1D<T> Array1D<T>::operator - (const Array1D<T>& v) const { if (size != v.size) throw SizeMismatch( ); Array1D<T> w(size); // Create result array w for (int i = 0; i < size; i++) w.element[i] = element[i] - v.element[i]; return w; } // return w=(*this)-v template <class T> Array1D<T> Array1D<T>::operator - ( ) const { Array1D<T> w(size); // Create result array w for (int i = 0; i < size; i++) w.element[i] = -element[i]; return w; } // return w=(*this)-v template <class T> Array1D<T>& Array1D<T> :: operator += (const T& x) { for (int i = 0; i < size; i++) element[i] += x; return *this ; } Program 4.5 Overloading binary minus, unary minus, and increment

  12. 4.1.5 The Class Array2D • A two-dimensional array is viewed as a collection of one-dimensional array. • 怎样将二维数组中元素存入到计算机内存中呢? • 数组一般不作插入或删除操作,一旦建立,则结构中的元素个数和相互间的关系就不再变动,即它们的逻辑结构不再发生变化。

  13. template <class T> class Array2D { public: Array2D (int r = 0, int c = 0); Array2D(const Array2D<T>& m); ~Array2D( ) { delete [ ] row; } int Rows( ) const { return rows; } int Columns( ) const { return cols; } Array1D<T>& operator [](int i) const ; Array2D<T>& operator = (const Array2D<T>& m); Array2D<T> operator + ( ) const ; Array2D<T> operator + (const Array2D<T>& m) const ; Array2D<T> operator - ( ) const ; // unary minus Array2D<T> operator - (const Array2D<T>& m) const ; Array2D<T> operator * (const Array2D<T>& m) const ; Array2D<T>& operator += (const T& x); private: int rows, cols; Array1D<T> *row; }; Program 4.6 A class for two-dimensional arrays

  14. template <class T> Array2D<T>::Array2D(int r, int c) { if (r < 0 || c < 0) throw BadInitializers( ); if ((!r || !c) && (r || c)) throw BadInitializers( ); rows = r; cols = c; row = new Array1D<T> [r]; for (int i = 0; i < r; i++) row [i].ReSize(c); } Program 4.7 Constructor for a two-dimensional array template <class T> Array2D<T>::Array2D(const Array2D<T>& m) { rows = m.rows; cols = m.cols; row = new Array1D<T> [rows]; for (int i = 0; i < rows; i++) row[i] = m.row[i]; } Program 4.8 Copy constructor for two-dimensional arrays template<class T> Array1D<T>& Array2D<T>::operator [ ] (int i) const { if (i < 0 || i >= rows) throw OutOfBounds( ); return row[i]; } Program 4.9 Overloading [ ] for a two-dimensional array

  15. template <class T>Array2D<T> Array2D<T>::operator - (const Array2D<T>& m) const { if (rows != m.rows || cols != m.cols) throw SizeMismatch( ); Array2D<T> w(rows,cols); for (int i = 0; i < rows; i++) w.row[i] = row[i] - m.row[i]; return w; } Program 4.10 Subtraction template <class T> Array2D<T> Array2D<T>::operator *(const Array2D<T>& m) const { if (cols != m.rows) throw SizeMismatch(); Array2D<T> w (rows, m.cols); for (int i = 0; i < rows; i++) for (int j = 0; j < m.cols; j++) { T sum = (*this )[i][0] * m[0][j]; for (int k = 1; k < cols; k++) sum += (*this )[ i ][ k ] * m[ k ][ j ]; w [i] [j] = sum;} return w; } Program 4.11 Matrix multiplication

  16. 4.2 MATRICES4.2.1 Definitions and Operations MT(i,j) = M(j,i), 1<i<n, 1<j<m C(i,j) = A (i,j) +B (i,j) c (i,j) =∑ A (i,k) *B (k,j)

  17. 4.2.2 The Class Matrix • An m x n matrix M all of whose elements are integer may be represented as a two-dimensional integer array int x[m][n] or Array2D <int> x[m] [n]

  18. Program 4.12 The class Matrix template <class T> class Matrix { public: Matrix (int r = 0, int c = 0); Matrix (const Matrix<T>& m); ~Matrix ( ) { delete [ ] element; }; int Rows ( ) const { return rows; } int Columns( ) const { return cols; } T& operator ( ) (int i, int j) const ; Matrix<T>& operator = (const Matrix<T>& m); Matrix<T>operator + ( ) const; //unary+ Matrix<T>operator + (const Matrix<T>& m)const; Matrix<T>operator - ( )const;// unary minus Matrix<T>operator - (constMatrix<T>& m)const; Matrix<T>operator * (constMatrix<T>& m)const; Matrix<T>&operator += (constT&x); private: int rows, cols; T *element; };

  19. Program 4.13 Matrix constructor template <class T> Matrix<T> :: Matrix (int r, int c) { if (r < 0 || c < 0) throw BadInitializers( ); if ((!r || !c) && (r || c)) throw BadInitializers( ); rows = r; cols = c; element = new T [r * c]; } Program 4.14 Indexing a matrix template <class T> T& Matrix<T> :: operator ( ) (int i, int j) const { // “( )” can take any number of parameters. if (i < 1 || i > rows || j < 1 || j > cols) throw OutOfBounds ( ); return element[(i - 1) * cols + j - 1]; }

  20. template <class T> Matrix<T> Matrix<T>: :operator - (const Matrix<T>& m) const { // Return (*this) - m. if (rows != m.rows || cols != m.cols) throw SizeMismatch(); // create result matrix w Matrix<T> w(rows, cols); for (int i = 0; i < rows * cols; i++) w.element[i] = element[i] - m.element[i]; return w; } Program 4.15 Matrix subtraction

  21. template <class T> Matrix<T> Matrix<T>::operator * (const Matrix<T>& m) const { if (cols != m.rows) throw SizeMismatch(); Matrix<T> w(rows, m.cols); // result matrix int ct = 0, cm = 0, cw = 0; for (int i = 1; i <= rows; i++) { for (int j = 1; j <= m.cols; j++) { T sum = element[ct] * m.element[cm]; for (int k = 2; k <= cols; k++) { ct++; cm += m.cols; // next in column j of m sum += element[ct] * m.element[cm]; } w.element[cw++] = sum; ct -= cols - 1; cm = j; } ct += cols; cm = 0; } return w; } Program 4.16 Matrix multiplication

  22. 4.3 SPECIAL MATRIXES4.3.1 Definitions and Applications • Square matrix • Diagonal(对角矩阵) • Tridiagonal(三对角矩阵) • Lower triangular(下三角矩阵) • Upper triangular (上三角矩阵) • Symmetric (对称矩阵)

  23. Example 4.3 Symmetric

  24. Example 4.4

  25. 4.3.2 Diagonal Matrices Program 4.17 The class DiagonalMatrix template <class T> class DiagonalMatrix { public: DiagonalMatrix (int size = 10) {n=size; d=newT [n];} ~DiagonalMatrix( ) { delete [ ] d; } DiagonalMatrix<T>& Store (const T& x, int i, int j); T Retrieve (int i,int j) const; private: int n; T *d; };

  26. template <class T> DiagonalMatrix<T>& DiagonalMatrix<T>::Store(const T& x, int i, int j) { if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds(); if (i != j && x != 0) throw MustBeZero(); if (i == j) d[i-1] = x; return *this ; } template <class T> T DiagonalMatrix<T>::Retrieve(int i, int j) const { // Retrieve D(i,j). if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds( ); if (i == j) return d[i-1]; else return 0; }

  27. 4.3.3 Tridiagonal Matrix • In an n*n trdiagonal matrix T. the nonzero elements lie on one of the three diagonals: • Main diagonal – for this, i = j. • Diagonalbelow main diagonal – for this, i = j+1. • Diagonal above mian diagonal – for this, i = j-1. • t [0:9]=[2,1,3,1,3,5,2,7,9,0] t = [2,3,1,1,5,3,2,9,7,0] t = [3,5,9,2,1,2,0,1,3,7]

  28. Program 4.18 The class TridiagonalMatrix template <class T>class TridiagonalMatrix { public: TridiagonalMatrix(int size = 10) { n = size; t = new T [3*n-2];} TridiagonalMatrix( ) { delete [ ] t; } TridiagonalMatrix<T>& Store (const T& x, int i, int j); T Retrieve(int i, int j) const ; private: int n; T *t; };

  29. template <class T>TridiagonalMatrix<T>& TridiagonalMatrix<T>::Store(const T& x, int i, int j) { if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds(); switch (i - j) { case 1: t[i - 2] = x; break ; case 0: t[n + i - 2] = x; break ; case -1: t[2 * n + i - 2] = x; break ; default: if (x != 0) throw MustBeZero(); } return *this ; }

  30. template <class T> T TridiagonalMatrix<T>::Retrieve(int i, int j) const { if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds(); switch (i - j) { case 1: return t[i - 2]; case 0: return t[n + i - 2]; case -1: return t[2 * n + i - 2]; default: return 0; } } Program 4.18 The class TridiagonalMatrix

  31. 4.3.4 Triangular Matrices

  32. Program 4.19 The class LowerMatrix template <class T> class LowerMatrix { public : LowerMatrix(int size = 10){ n = size; t = new T[n*(n+1)/2]; } ~LowerMatrix( ) { delete [ ] t; } LowerMatrix<T>& Store ( const T& x, int i, int j ); T Retrieve(int i, int j) const ; private : int n; // matrix dimension T *t; // 1D array for lower triangle };

  33. template <class T> LowerMatrix<T>& LowerMatrix<T>::Store(const T& x, int i, int j) { if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds( ); if (i >= j) t[i*(i-1)/2+j-1] = x; else if (x != 0) throw MustBeZero(); return *this ; } template <class T> T LowerMatrix<T>::Retrieve(int i, int j) const { if (i < 1 || j < 1 || i > n || j > n) throw OutOfBounds( ); if (i >= j) return t[i*(i-1)/2+j-1]; else return 0; }

  34. 4.3.5 Symmetric Matrices

  35. 4.4 Sparse Matrices(稀疏矩阵)4.4.1 Motivation • 什么是稀疏矩阵?矩阵的许多元素为0 • 如何进行压缩存储?三元组表示(i, j, aij) • An m x n matrix is said to be sparse if many of its elements are zero. A matrix that is not sparse is dense.

  36. 4.4.2 Array Representation

  37. template <class T> class SparseMatrix { friend ostream& operator << (ostream&, const SparseMatrix<T>&); friend istream& operator >> (istream&, SparseMatrix<T>&); public: SparseMatrix(int maxTerms = 10); ~SparseMatrix() { delete [ ] a; } void Transpose(SparseMatrix<T> &b) const; void Add(const SparseMatrix<T> &b, SparseMatrix<T> &c) const; private : void Append(const Term<T>& t); int rows, cols, terms, MaxTerms; Term<T> *a; }; Program 4.20 The class SparseMatrix

  38. Program 4.21 SparseMatrix constructor template <class T> SparseMatrix<T>::SparseMatrix(int maxTerms) { if (maxTerms < 1) throw BadInitializers(); MaxTerms = maxTerms; a = new Term<T> [MaxTerms]; terms = rows = cols = 0; }

  39. template <class T> ostream& operator << (ostream& out, const SparseMatrix<T>& x) { out << "rows=" << x.rows << "columns=“ << x.cols << endl; out << "nonzero terms = " << x.terms << endl; for (int i = 0; i < x.terms; i++) out<<"a("<< x.a[i].row<<', '<<x.a[i].col<<") ="<<x.a[i].value<<endl; return out; } template <class T> istream& operator >>(istream& in, SparseMatrix<T>& x) { cout << "Enter number of rows, columns, and terms" << endl; in >> x.rows >> x.cols >> x.terms; if (x.terms > x.MaxTerms) throw NoMem( ); for (int i = 0; i < x.terms; i++) { cout << "Enter row, column, and value of term" << (i + 1) << endl; in >> x.a[i].row >> x.a[i].col >> x.a[i].value; } return in; } Program 4.22 SparseMatrix input and output Codes

  40. template <class T> //转置结果在b中 void SparseMatrix<T>::Transpose(SparseMatrix<T> &b) const { if (terms > b.MaxTerms) throw NoMem(); b.cols = rows; b.rows = cols; b.terms = terms; //设转置特征 int *ColSize, *RowNext; ColSize = new int [cols + 1]; RowNext = new int [rows + 1]; for (int i = 1; i <= cols; i++) ColSize[i] = 0; for (int i = 0; i < terms; i++) ColSize[a[i].col]++; RowNext[1] = 0; for (int i = 2; i <= cols; i++) RowNext[i] = RowNext[i - 1] + ColSize[i - 1]; for (int i = 0; i < terms; i++) { //执行转置 int j = RowNext[a[i].col]++; b.a[j].row = a[i].col; b.a[j].col = a[i].row; b.a[j].value = a[i].value; } } Program 4.23 Transposing a sparse matrix

  41. Program 4.24 Appending a non-zero term template <class T> void SparseMatrix<T>::Append(const Term<T>& t) { // Append a nonzero term t to *this. if (terms >= MaxTerms) throw NoMem(); a[terms] = t; terms++; }

  42. Program 4.25 Adding two sparse matrices template<class T> // C =(*this) + b void SparseMatrix<T>::Add( const SparseMatrix<T>&b, SparseMatrix<T> &c) const { if (rows != b.rows || cols != b.cols) throw SizeMismatch( ); c.rows = rows; c.cols = cols; c.terms = 0; int ct = 0, cb = 0; while (ct<terms && cb<b.terms) {// 在*this和b中遍历 int indt = a[ct].row * cols + a[ct].col; int indb = b.a[cb].row * cols + b.a[cb].col; if (indt < indb) { c.Append(a[ct]); ct++; }

  43. else { if (indt == indb) { if (a[ct].value + b.a[cb].value) { term <T> t; t.row = a[ct].row;t.col=a[ct].col; t.value=a[ct].value+b.a[cb].value; c.append(t);} ct++; cb++;} else { c.append(b.a[cb]); cb++; } } } for (; ct<terms; ct++) c.append (a[ct]); for (; cb<b.terms; cb++) c.append(b.a[cb]); } Program 4.25 Adding two sparse matrices

  44. 4.4.3 Linked Representation • A shortcoming of the one-dimensional array representation of a sparse matrix is that we need to know the number of nonzero terms in each of the sparse matrices.

  45. 1. The representation(含行指针的链表) 0 0 0 2 0 0 1 0 0 6 0 0 7 0 0 3 0 0 0 9 0 8 0 0 0 4 5 0 0 0 0 0 • Chain Node Types • Chain <Cnode<T>>

  46. template <class T> class CNode { public: int operator != (const CNode<T>& y) { return (value != y.value);} void Output(ostream& out) const { out << "column " << col << " value " << value; } private: int col; T value; }; template <class T> ostream& operator << (ostream& out, const CNode<T>& x) { x.Output(out); out << endl; return out; }

  47. template <class T> class HeadNode { public: int operator !=(const HeadNode<T>& y){return (row!=y.row);} void Output(ostream& out) const { out << "row " << row; } private : int row; Chain<CNode<T>> a; }; // row chain template <class T> ostream& operator (ostream& out, const HeadNode<T>& x) { x.Output(out); out << endl; return out; } Program 4.26 Chain nodes used in sparse matrix representation

  48. 3. The Class LinkedMatrix template <class T> class LinkedMatrix { public: LinkedMatrix( ) { }; ~LinkedMatrix( ) { } ; void Transpose(LinkedMatrix<T> &b) const ; void Add(const LinkedMatrix<T> &b, LinkedMatrix<T>&c)const ; private : int rows, cols; Chain<HeadNode<T> > a; }; Program 4.27 Class definition for a linked sparse matrix

  49. 4. Overloading >> template<class T> istream& operator >> (istream& in, LinkedMatrix<T>& x) { x.a.Erase( ); int terms; cout << "Enter number of rows,columns," << "and terms" << endl; in >> x.rows >> x.cols >> terms; HeadNode<T> H; H.row = 0; for (int i = 1; i <= terms ; i++) { cout<<"Enter row,column and "<<"value of term"<< i << endl; int row, col; T value; in >> row >> col >> value; if (row > H.row) { if (H.row) x.a.Append(H);

More Related