EDN Admin
Well-known member
HI
Anyone can help me to debug the following c++ code. when the sub program iteratively, the memory is going up. In the program, orthogonal list is used.
The main.cpp
#include <iostream><br/>
#include "stdlib.h"<br/>
#include "stdio.h"<br/>
#include "string.h"<br/>
#include "Sparsematrix.h"<br/>
#include "math.h"
<br/>
void testt()<br/>
{<br/>
int *Maxa, *Mht ;<br/>
int ip, idf, Neq, Nwk;<br/>
int i, j, k, l, kk;<br/>
<br/>
int *Leq ; <br/>
double *For;<br/>
int **Ifp;<br/>
int **Lm;<br/>
int NPoin=2541, NElem=2000;<br/>
int Ndf=3, Nnd=8;
Ifp = new int*[NPoin];<br/>
for (i=0; i<NPoin; i++)<br/>
Ifp = new int[Ndf] ;
for (i=0; i<NPoin; i++)<br/>
{<br/>
for(j=0; j<Ndf; j++)<br/>
Ifp[j] = 0;<br/>
}
Lm = new int*[NElem] ;<br/>
for (i=0; i<NElem; i++)<br/>
{<br/>
Lm = new int[Nnd*Ndf] ;
for (j=0; j<Nnd*Ndf; j++)<br/>
Lm[j] = 0;<br/>
}<br/>
<br/>
Neq = 0;<br/>
for (ip=0; ip<NPoin; ip++)<br/>
{<br/>
for (idf=0; idf<Ndf; idf++ )<br/>
{ <br/>
if ( Ifp[ip][idf] == 0 ) <br/>
{<br/>
Neq ++ ;<br/>
Ifp[ip][idf] = Neq ;<br/>
}<br/>
else<br/>
Ifp[ip][idf] = 0 ;<br/>
}<br/>
}<br/>
<br/>
Maxa = new int[Neq+1] ;<br/>
Mht = new int[Neq] ;<br/>
For = new double[Neq+1] ;<br/>
<br/>
for ( i=0; i<Neq; i++ )<br/>
{<br/>
Maxa = 0 ;<br/>
Mht = 0 ;<br/>
For = 0 ;<br/>
}<br/>
Maxa[Neq] = 0 ;<br/>
For[Neq] = 0;
<br/>
CSparseMatrix Gkk(Neq+1, Neq+1);<br/>
for ( i=0; i<NPoin; i++ )<br/>
{<br/>
for ( j=0; j<Ndf; j++ )<br/>
{<br/>
kk = abs(Ifp[j]) ;<br/>
if (kk > 0)<br/>
{<br/>
For[kk] += 2 ;<br/>
}<br/>
}<br/>
}
Nwk = Maxa[Neq] - Maxa[0] ;
int m, n, pn;<br/>
for ( i=0; i<NElem; i++ )<br/>
{<br/>
<br/>
Leq = new int[Nnd*Ndf] ;<br/>
for ( j=0; j<Nnd*Ndf; j++ )<br/>
{<br/>
Leq[j] = Lm[j] ;<br/>
}
k = Nnd * Ndf;<br/>
<br/>
for ( j=0; j<Ndf*Nnd; j++ )<br/>
{<br/>
m = Lm[j] ;<br/>
if (m > 0)<br/>
{ <br/>
for (n=0; n<Ndf*Nnd; n++)<br/>
{<br/>
<br/>
l = Lm[n] ;<br/>
if (l > 0)<br/>
{<br/>
Gkk(m, l) = Gkk(m, l) + 12;
}<br/>
} <br/>
}<br/>
}
delete[] Leq;<br/>
}
int Nnz;<br/>
Nnz = 0;<br/>
double toler= 1e-15;
Gkk.DelAllNode();
for (i=0; i<NPoin; i++)<br/>
{<br/>
delete []Ifp; <br/>
Ifp = NULL;
}<br/>
delete []Ifp;<br/>
Ifp = NULL;
for (i=0; i<NElem; i++)<br/>
{<br/>
delete []Lm; <br/>
}<br/>
delete[] Lm;<br/>
<br/>
delete []Maxa;<br/>
delete []Mht;<br/>
delete []For;<br/>
}
int main()<br/>
{<br/>
int i;<br/>
for (i=0; i<3000; i++)<br/>
testt() ;
return 0;<br/>
}
the following is Sparsematrix.h
/**/<br/>
#ifndef _SPARSEMATRIX_H_<br/>
#define _SPARSEMATRIX_H_
struct MatrixNode <br/>
{ <br/>
int row;<br/>
int col;<br/>
double val;<br/>
MatrixNode *right;<br/>
MatrixNode *down;<br/>
};
class CSparseMatrix <br/>
{ <br/>
public: //construct function <br/>
<br/>
CSparseMatrix(CSparseMatrix &rhs); //拷贝构造函数<br/>
CSparseMatrix(int row, int col); //构造函数
protected :
int m_row; //矩阵的行数<br/>
int m_col; //矩阵的列数
public:
MatrixNode **pRhead; //矩阵的行头节点<br/>
MatrixNode **pChead; //矩阵的列头节点<br/>
int nNumOfNode; //矩阵的节点数目
public: //initialization of the matrix<br/>
<br/>
void InitMatrix(); //初始化矩阵头指针<br/>
// void ReadData(); //为矩阵读入数据<br/>
void SetRow( int ); //设置矩阵的行数<br/>
void SetCol( int ); //设置矩阵的列数<br/>
<br/>
public: //矩阵的基本运算<br/>
<br/>
CSparseMatrix TransposeSMatrix(); //转置矩阵
<br/>
void InsertNode(int i,int j,double val); //插入节点到指定位置<br/>
double & InsertNode(int i,int j); //插入节点到指定位置<br/>
void ChangeNodeValue(int i,int j,double value); //改变指定节点的值<br/>
void AddNodeValue(int i, int j, double value); //增加指定节点的值<br/>
void RemoveNode(int i,int j); //删除指定节点<br/>
void DelAllNode(); //删除所有非零节点,以及头指针<br/>
void IncreaseNode(){++nNumOfNode; }; //增加节点数目<br/>
void DecreaseNode(){--nNumOfNode;}; //减少节点数目<br/>
long GetNumOfNode(){return nNumOfNode;} //取得非零节点的数目<br/>
double GetData(int i,int j); //取得指定位置的任意元素
<br/>
int GetRow()const ; //得到矩阵的行数<br/>
int GetCol()const ; //得到矩阵的列数
public: //重载运算符函数,友元函数<br/>
<br/>
double & operator()(int row, int col);
public : //析构函数<br/>
~CSparseMatrix();
<br/>
};
<br/>
#endif
the following is Sparsematrix.cpp:
#include "Sparsematrix.h"<br/>
#include <math.h><br/>
#include <stdlib.h><br/>
#include "stdio.h"<br/>
<br/>
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的行数 *<br/>
/*
*<br/>
/********************************************************/<br/>
void inline CSparseMatrix::SetRow (int row)<br/>
{<br/>
m_row=row;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的列数 *<br/>
/*
*<br/>
/********************************************************/<br/>
void inline CSparseMatrix::SetCol (int col)<br/>
{<br/>
m_col=col;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 返回矩阵的列数 *<br/>
/*
*<br/>
/********************************************************/<br/>
int CSparseMatrix::GetRow ()const<br/>
{<br/>
return m_row;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 返回矩阵的行数 *<br/>
/*
*<br/>
/********************************************************/<br/>
int CSparseMatrix::GetCol ()const<br/>
{<br/>
return m_col;<br/>
}<br/>
<br/>
/********************************************************/<br/>
/* 初始化矩阵
*<br/>
/* 生成稀疏矩阵的行列头指针 *<br/>
/*
*<br/>
/********************************************************/
CSparseMatrix::CSparseMatrix(int row,int col)<br/>
{ <br/>
if(row <= 0) <br/>
{ <br/>
printf("矩阵初始化的行参数错误!");<br/>
exit(0); <br/>
} <br/>
if(col <= 0) <br/>
{ <br/>
printf("矩阵初始化的列参数错误!");<br/>
exit(0); <br/>
}<br/>
SetRow(row); //设置行数<br/>
SetCol(col); //设置列数<br/>
InitMatrix(); //初始化矩阵
<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的行列头指针 *<br/>
/* 节点数目
*<br/>
/********************************************************/<br/>
void CSparseMatrix::InitMatrix ()<br/>
{<br/>
nNumOfNode =0;<br/>
int i;<br/>
pRhead =new MatrixNode*[GetRow()+1]; //为行的头指针分配空间<br/>
for(i=1;i<GetRow()+1;i++) //并赋初值为NULL<br/>
pRhead =NULL;<br/>
pChead =new MatrixNode*[GetCol()+1]; //为列的头指针分配空间
<br/>
for( i=1;i<GetCol()+1;i++) //并赋初值为NULL<br/>
pChead =NULL;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 拷贝构造函数 *<br/>
/*
*<br/>
/********************************************************/<br/>
CSparseMatrix::CSparseMatrix(CSparseMatrix &rhs)<br/>
{<br/>
MatrixNode *q,*p;<br/>
double val;
SetRow(rhs.GetRow()); //设置行数<br/>
SetCol(rhs.GetCol()); //设置列数
<br/>
InitMatrix(); //初始化矩阵
<br/>
for(int i=1;i<rhs.GetRow ()+1;i++) <br/>
{ <br/>
q=rhs. pRhead ; //寻找非零节点<br/>
if(!q) continue; //为新矩阵赋值<br/>
for(int j=1;j<rhs.GetCol ()+1;j++)<br/>
{<br/>
p=rhs.pChead [j];<br/>
if(!p) continue;<br/>
val=rhs.GetData(i,j);<br/>
InsertNode (i,j,val); //为新矩阵插入非零节点
<br/>
nNumOfNode =rhs.nNumOfNode ;
<br/>
}//j<br/>
}//i
delete p, q;
}
/********************************************************/<br/>
/*
*<br/>
/* 插入元素到指定的位置 *<br/>
/*
*<br/>
/********************************************************/<br/>
void CSparseMatrix::InsertNode(int i, int j, double val)<br/>
{<br/>
if(i < 0 || i>GetRow ()+1 ) //参数检查<br/>
{<br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j < 0 || j>GetCol()+1 )<br/>
{ <br/>
<br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p,*s;<br/>
p=NULL;<br/>
q= pRhead ;
<br/>
<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被增加的节点前一位 <br/>
p=q; q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j))<br/>
{<br/>
s=new MatrixNode; //增加节点<br/>
IncreaseNode();<br/>
s->row=i; //为节点赋置<br/>
s->col =j;<br/>
s->val =val;<br/>
if(p==NULL) //如果为第一个节点<br/>
{ //就把地址存入该行头节点
<br/>
s->right = pRhead ; <br/>
pRhead =s;<br/>
}<br/>
else <br/>
{<br/>
s->right =q; //如果不是第一个节点<br/>
p->right =s; //调整该行的链接关系<br/>
}<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while((q!=NULL) && (q->row <i)) <br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if(p==NULL)<br/>
{ //如果为第一个节点<br/>
s->down = pChead [j]; //就把地址存入该列头节点
<br/>
pChead [j] =s;<br/>
}<br/>
else<br/>
{ //如果不是第一个节点<br/>
s->down =q; //调整该列的链接关系<br/>
p->down =s;<br/>
}<br/>
}<br/>
}<br/>
/**********************************************************/<br/>
/* 改变指定位置的元素 *<br/>
/*
*<br/>
/* i,j分别为行列下标 *
<br/>
/**********************************************************/<br/>
void CSparseMatrix::ChangeNodeValue(int i,int j,double value)<br/>
{<br/>
if(i <= 0 || i>GetRow () ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(1); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(2); <br/>
}
MatrixNode *q,*p;<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j)) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j)) <br/>
{<br/>
printf("节点不存在!");<br/>
return ;<br/>
}<br/>
q->val =value; //改变节点的值
<br/>
}
/************************************************************/<br/>
/* 给指定位置的元素增加一个值,若该元素为空, *<br/>
/* 则为该元素分配内存并赋值. *<br/>
/* 该函数主要用来形成装配整体结构刚度矩阵 *<br/>
/* i, j分别为行列下标 *
<br/>
/************************************************************/<br/>
void CSparseMatrix::AddNodeValue (int i, int j, double value)<br/>
{<br/>
if(i <= 0 || i>GetRow () ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(1); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(2); <br/>
}
MatrixNode *q, *p;<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j)) //定位指定的非零节点<br/>
{
<br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j)) <br/>
{<br/>
InsertNode(i, j, value); //若该元素为空, 则为该元素分配内存并赋值<br/>
}<br/>
else<br/>
{<br/>
q->val += value; //增加节点的值
<br/>
}
}
<br/>
/********************************************************/<br/>
/* 删除指定位置的元素 *
<br/>
/*
*<br/>
/* i,j分别为行列下标 *<br/>
/********************************************************/<br/>
void CSparseMatrix::RemoveNode (int i, int j)<br/>
{<br/>
if(i <= 0 || i>GetRow() ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q= pRhead ;<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->right ;<br/>
};
if(q==NULL || q->col >j )
<br/>
return;<br/>
else <br/>
{<br/>
if(p==NULL) //重新设定行的链接关系<br/>
pRhead =q->right ;<br/>
else p->right =q->right ;<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while(q->row <i) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->down ;<br/>
<br/>
};<br/>
if(p==NULL) pChead [j]=q->down ; //重新设定列的链接关系<br/>
else p->down =q->down ;<br/>
delete q;<br/>
DecreaseNode();<br/>
}<br/>
delete p;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 删除矩阵中的所有元素,释放内存 *<br/>
/*
*<br/>
/********************************************************/<br/>
void CSparseMatrix:elAllNode ()<br/>
{ <br/>
int i;<br/>
if(nNumOfNode==0) return ;<br/>
MatrixNode *q,*p;<br/>
/**/<br/>
for(i=1;i<GetRow()+1;i++) //该for循环用于从每行中删除非零节点<br/>
{ <br/>
p=q=pRhead;<br/>
if(!q)continue; //该行无元素,结束该次循环<br/>
while(q)<br/>
{<br/>
p=q->right ; //下一个节点的指针存储在p中<br/>
delete q;<br/>
q=p; //q指向下一个节点<br/>
}
}//i
for( i=1;i<GetRow()+1;i++) <br/>
{//将行指针赋值为空 <br/>
// delete []pRhead;<br/>
pRhead =NULL; <br/>
}<br/>
// delete []pRhead;<br/>
// pRhead = NULL;<br/>
<br/>
for( i=1;i<GetCol()+1;i++)<br/>
{//将列指针赋值为空 <br/>
// delete []pChead ;<br/>
pChead =NULL;<br/>
}<br/>
// delete []pChead ;<br/>
// pChead = NULL ;
nNumOfNode=0; //数组元素清零
<br/>
delete p, q;<br/>
}
/********************************************************/<br/>
/* 取得指定位置任意的元素 *<br/>
/*
*<br/>
/* i为行下标,j 为列下标 *<br/>
/********************************************************/<br/>
double CSparseMatrix::GetData (int i, int j)<br/>
{ <br/>
if(i <= 0 || i>GetRow() ) //行列参数检查<br/>
{
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q=NULL;<br/>
if(i>=j) //如果行数>列数,就从行开始寻找非零节点 <br/>
{<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j) )<br/>
{ <br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL)||(q->col>j)) return 0; //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
else //如果行数<列数,就从列开始寻找非零节点<br/>
{ <br/>
q=pChead [j];<br/>
while((q!=NULL) && (q->row <i))<br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if((q==NULL)||(q->row >i)) return 0; //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 矩阵转置运算 *<br/>
/*
*<br/>
/********************************************************/<br/>
CSparseMatrix CSparseMatrix::TransposeSMatrix(){<br/>
CSparseMatrix At(this->GetCol() ,this->GetRow ());<br/>
MatrixNode *q;<br/>
double x;<br/>
for(int i=1;i<GetRow()+1;i++)<br/>
{<br/>
q= pRhead ;<br/>
if(!q) continue; //该行无元素,退出此次循环<br/>
for(int j=1;j<GetCol()+1;j++)<br/>
{<br/>
q= pChead [j];<br/>
if(!q) continue; //该列无元素,退出此次循环<br/>
x=GetData(i,j);<br/>
if(x) <br/>
{<br/>
At.InsertNode (j,i,x);<br/>
}<br/>
}//j<br/>
<br/>
}//i<br/>
return At;<br/>
}
CSparseMatrix::~CSparseMatrix ()<br/>
{<br/>
if(nNumOfNode==0) return ;<br/>
MatrixNode *q,*p;<br/>
for(int i=1;i<GetRow()+1;i++) //该for循环用于从每行中删除非零节点<br/>
{ <br/>
p=q=pRhead;<br/>
<br/>
while(q)<br/>
{<br/>
p=q->right ; //下一个节点的指针存储在p中<br/>
delete q;<br/>
q=p; //q指向下一个节点<br/>
}
}//i<br/>
nNumOfNode=0;<br/>
delete []pRhead; //删除行,列头节点<br/>
delete []pChead;
}
double & CSparseMatrix::InsertNode(int i,int j)<br/>
{<br/>
if(i < 0 || i>GetRow ()+1 ) //参数检查<br/>
{<br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j < 0 || j>GetCol()+1 )<br/>
{ <br/>
<br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p,*s;<br/>
p=NULL;<br/>
q= pRhead ;
<br/>
<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被增加的节点前一位 <br/>
p=q; q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j))<br/>
{<br/>
s=new MatrixNode; //增加节点<br/>
IncreaseNode();<br/>
s->row=i; //为节点赋置<br/>
s->col =j;<br/>
s->val =0;<br/>
if(p==NULL) //如果为第一个节点<br/>
{ //就把地址存入该行头节点
<br/>
s->right = pRhead ; <br/>
pRhead =s;<br/>
}<br/>
else <br/>
{<br/>
s->right =q; //如果不是第一个节点<br/>
p->right =s; //调整该行的链接关系<br/>
}<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while((q!=NULL) && (q->row <i)) <br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if(p==NULL)<br/>
{ //如果为第一个节点<br/>
s->down = pChead [j]; //就把地址存入该列头节点
<br/>
pChead [j] =s;<br/>
}<br/>
else<br/>
{ //如果不是第一个节点<br/>
s->down =q; //调整该列的链接关系<br/>
p->down =s;<br/>
}<br/>
}<br/>
return s->val;<br/>
}
<br/>
double & CSparseMatrix:perator()(int i, int j)<br/>
{<br/>
if(i <= 0 ) //行列参数检查<br/>
{ <br/>
printf("传入的行参数错误----!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
if(i>GetRow() ) //行列参数检查<br/>
{ <br/>
SetRow(i);<br/>
} <br/>
<br/>
if(j>GetCol() ) <br/>
{ <br/>
SetCol(j);<br/>
}
<br/>
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q=NULL;<br/>
if(i>=j) //如果行数>列数,就从行开始寻找非零节点 <br/>
{<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j) )<br/>
{ <br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL)||(q->col>j)) return InsertNode(i, j); //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
else //如果行数<列数,就从列开始寻找非零节点<br/>
{ <br/>
q=pChead [j];<br/>
while((q!=NULL) && (q->row <i))<br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if((q==NULL)||(q->row >i)) return InsertNode(i, j); //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
p=NULL;<br/>
q=NULL;<br/>
delete []q; //删除行,列头节点<br/>
delete []p;
}
/*<br/>
void InvertMatrix(CSparseMatrix &TM)<br/>
{<br/>
int i, j, n, k;<br/>
double temp;<br/>
<br/>
n = TM.GetCol();<br/>
<br/>
CSparseMatrix a(n, n);<br/>
CSparseMatrix b(n, n);<br/>
CSparseMatrix c(n, n);<br/>
<br/>
}
*/
View the full article
Anyone can help me to debug the following c++ code. when the sub program iteratively, the memory is going up. In the program, orthogonal list is used.
The main.cpp
#include <iostream><br/>
#include "stdlib.h"<br/>
#include "stdio.h"<br/>
#include "string.h"<br/>
#include "Sparsematrix.h"<br/>
#include "math.h"
<br/>
void testt()<br/>
{<br/>
int *Maxa, *Mht ;<br/>
int ip, idf, Neq, Nwk;<br/>
int i, j, k, l, kk;<br/>
<br/>
int *Leq ; <br/>
double *For;<br/>
int **Ifp;<br/>
int **Lm;<br/>
int NPoin=2541, NElem=2000;<br/>
int Ndf=3, Nnd=8;
Ifp = new int*[NPoin];<br/>
for (i=0; i<NPoin; i++)<br/>
Ifp = new int[Ndf] ;
for (i=0; i<NPoin; i++)<br/>
{<br/>
for(j=0; j<Ndf; j++)<br/>
Ifp[j] = 0;<br/>
}
Lm = new int*[NElem] ;<br/>
for (i=0; i<NElem; i++)<br/>
{<br/>
Lm = new int[Nnd*Ndf] ;
for (j=0; j<Nnd*Ndf; j++)<br/>
Lm[j] = 0;<br/>
}<br/>
<br/>
Neq = 0;<br/>
for (ip=0; ip<NPoin; ip++)<br/>
{<br/>
for (idf=0; idf<Ndf; idf++ )<br/>
{ <br/>
if ( Ifp[ip][idf] == 0 ) <br/>
{<br/>
Neq ++ ;<br/>
Ifp[ip][idf] = Neq ;<br/>
}<br/>
else<br/>
Ifp[ip][idf] = 0 ;<br/>
}<br/>
}<br/>
<br/>
Maxa = new int[Neq+1] ;<br/>
Mht = new int[Neq] ;<br/>
For = new double[Neq+1] ;<br/>
<br/>
for ( i=0; i<Neq; i++ )<br/>
{<br/>
Maxa = 0 ;<br/>
Mht = 0 ;<br/>
For = 0 ;<br/>
}<br/>
Maxa[Neq] = 0 ;<br/>
For[Neq] = 0;
<br/>
CSparseMatrix Gkk(Neq+1, Neq+1);<br/>
for ( i=0; i<NPoin; i++ )<br/>
{<br/>
for ( j=0; j<Ndf; j++ )<br/>
{<br/>
kk = abs(Ifp[j]) ;<br/>
if (kk > 0)<br/>
{<br/>
For[kk] += 2 ;<br/>
}<br/>
}<br/>
}
Nwk = Maxa[Neq] - Maxa[0] ;
int m, n, pn;<br/>
for ( i=0; i<NElem; i++ )<br/>
{<br/>
<br/>
Leq = new int[Nnd*Ndf] ;<br/>
for ( j=0; j<Nnd*Ndf; j++ )<br/>
{<br/>
Leq[j] = Lm[j] ;<br/>
}
k = Nnd * Ndf;<br/>
<br/>
for ( j=0; j<Ndf*Nnd; j++ )<br/>
{<br/>
m = Lm[j] ;<br/>
if (m > 0)<br/>
{ <br/>
for (n=0; n<Ndf*Nnd; n++)<br/>
{<br/>
<br/>
l = Lm[n] ;<br/>
if (l > 0)<br/>
{<br/>
Gkk(m, l) = Gkk(m, l) + 12;
}<br/>
} <br/>
}<br/>
}
delete[] Leq;<br/>
}
int Nnz;<br/>
Nnz = 0;<br/>
double toler= 1e-15;
Gkk.DelAllNode();
for (i=0; i<NPoin; i++)<br/>
{<br/>
delete []Ifp; <br/>
Ifp = NULL;
}<br/>
delete []Ifp;<br/>
Ifp = NULL;
for (i=0; i<NElem; i++)<br/>
{<br/>
delete []Lm; <br/>
}<br/>
delete[] Lm;<br/>
<br/>
delete []Maxa;<br/>
delete []Mht;<br/>
delete []For;<br/>
}
int main()<br/>
{<br/>
int i;<br/>
for (i=0; i<3000; i++)<br/>
testt() ;
return 0;<br/>
}
the following is Sparsematrix.h
/**/<br/>
#ifndef _SPARSEMATRIX_H_<br/>
#define _SPARSEMATRIX_H_
struct MatrixNode <br/>
{ <br/>
int row;<br/>
int col;<br/>
double val;<br/>
MatrixNode *right;<br/>
MatrixNode *down;<br/>
};
class CSparseMatrix <br/>
{ <br/>
public: //construct function <br/>
<br/>
CSparseMatrix(CSparseMatrix &rhs); //拷贝构造函数<br/>
CSparseMatrix(int row, int col); //构造函数
protected :
int m_row; //矩阵的行数<br/>
int m_col; //矩阵的列数
public:
MatrixNode **pRhead; //矩阵的行头节点<br/>
MatrixNode **pChead; //矩阵的列头节点<br/>
int nNumOfNode; //矩阵的节点数目
public: //initialization of the matrix<br/>
<br/>
void InitMatrix(); //初始化矩阵头指针<br/>
// void ReadData(); //为矩阵读入数据<br/>
void SetRow( int ); //设置矩阵的行数<br/>
void SetCol( int ); //设置矩阵的列数<br/>
<br/>
public: //矩阵的基本运算<br/>
<br/>
CSparseMatrix TransposeSMatrix(); //转置矩阵
<br/>
void InsertNode(int i,int j,double val); //插入节点到指定位置<br/>
double & InsertNode(int i,int j); //插入节点到指定位置<br/>
void ChangeNodeValue(int i,int j,double value); //改变指定节点的值<br/>
void AddNodeValue(int i, int j, double value); //增加指定节点的值<br/>
void RemoveNode(int i,int j); //删除指定节点<br/>
void DelAllNode(); //删除所有非零节点,以及头指针<br/>
void IncreaseNode(){++nNumOfNode; }; //增加节点数目<br/>
void DecreaseNode(){--nNumOfNode;}; //减少节点数目<br/>
long GetNumOfNode(){return nNumOfNode;} //取得非零节点的数目<br/>
double GetData(int i,int j); //取得指定位置的任意元素
<br/>
int GetRow()const ; //得到矩阵的行数<br/>
int GetCol()const ; //得到矩阵的列数
public: //重载运算符函数,友元函数<br/>
<br/>
double & operator()(int row, int col);
public : //析构函数<br/>
~CSparseMatrix();
<br/>
};
<br/>
#endif
the following is Sparsematrix.cpp:
#include "Sparsematrix.h"<br/>
#include <math.h><br/>
#include <stdlib.h><br/>
#include "stdio.h"<br/>
<br/>
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的行数 *<br/>
/*
*<br/>
/********************************************************/<br/>
void inline CSparseMatrix::SetRow (int row)<br/>
{<br/>
m_row=row;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的列数 *<br/>
/*
*<br/>
/********************************************************/<br/>
void inline CSparseMatrix::SetCol (int col)<br/>
{<br/>
m_col=col;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 返回矩阵的列数 *<br/>
/*
*<br/>
/********************************************************/<br/>
int CSparseMatrix::GetRow ()const<br/>
{<br/>
return m_row;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 返回矩阵的行数 *<br/>
/*
*<br/>
/********************************************************/<br/>
int CSparseMatrix::GetCol ()const<br/>
{<br/>
return m_col;<br/>
}<br/>
<br/>
/********************************************************/<br/>
/* 初始化矩阵
*<br/>
/* 生成稀疏矩阵的行列头指针 *<br/>
/*
*<br/>
/********************************************************/
CSparseMatrix::CSparseMatrix(int row,int col)<br/>
{ <br/>
if(row <= 0) <br/>
{ <br/>
printf("矩阵初始化的行参数错误!");<br/>
exit(0); <br/>
} <br/>
if(col <= 0) <br/>
{ <br/>
printf("矩阵初始化的列参数错误!");<br/>
exit(0); <br/>
}<br/>
SetRow(row); //设置行数<br/>
SetCol(col); //设置列数<br/>
InitMatrix(); //初始化矩阵
<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 初始化矩阵的行列头指针 *<br/>
/* 节点数目
*<br/>
/********************************************************/<br/>
void CSparseMatrix::InitMatrix ()<br/>
{<br/>
nNumOfNode =0;<br/>
int i;<br/>
pRhead =new MatrixNode*[GetRow()+1]; //为行的头指针分配空间<br/>
for(i=1;i<GetRow()+1;i++) //并赋初值为NULL<br/>
pRhead =NULL;<br/>
pChead =new MatrixNode*[GetCol()+1]; //为列的头指针分配空间
<br/>
for( i=1;i<GetCol()+1;i++) //并赋初值为NULL<br/>
pChead =NULL;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 拷贝构造函数 *<br/>
/*
*<br/>
/********************************************************/<br/>
CSparseMatrix::CSparseMatrix(CSparseMatrix &rhs)<br/>
{<br/>
MatrixNode *q,*p;<br/>
double val;
SetRow(rhs.GetRow()); //设置行数<br/>
SetCol(rhs.GetCol()); //设置列数
<br/>
InitMatrix(); //初始化矩阵
<br/>
for(int i=1;i<rhs.GetRow ()+1;i++) <br/>
{ <br/>
q=rhs. pRhead ; //寻找非零节点<br/>
if(!q) continue; //为新矩阵赋值<br/>
for(int j=1;j<rhs.GetCol ()+1;j++)<br/>
{<br/>
p=rhs.pChead [j];<br/>
if(!p) continue;<br/>
val=rhs.GetData(i,j);<br/>
InsertNode (i,j,val); //为新矩阵插入非零节点
<br/>
nNumOfNode =rhs.nNumOfNode ;
<br/>
}//j<br/>
}//i
delete p, q;
}
/********************************************************/<br/>
/*
*<br/>
/* 插入元素到指定的位置 *<br/>
/*
*<br/>
/********************************************************/<br/>
void CSparseMatrix::InsertNode(int i, int j, double val)<br/>
{<br/>
if(i < 0 || i>GetRow ()+1 ) //参数检查<br/>
{<br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j < 0 || j>GetCol()+1 )<br/>
{ <br/>
<br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p,*s;<br/>
p=NULL;<br/>
q= pRhead ;
<br/>
<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被增加的节点前一位 <br/>
p=q; q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j))<br/>
{<br/>
s=new MatrixNode; //增加节点<br/>
IncreaseNode();<br/>
s->row=i; //为节点赋置<br/>
s->col =j;<br/>
s->val =val;<br/>
if(p==NULL) //如果为第一个节点<br/>
{ //就把地址存入该行头节点
<br/>
s->right = pRhead ; <br/>
pRhead =s;<br/>
}<br/>
else <br/>
{<br/>
s->right =q; //如果不是第一个节点<br/>
p->right =s; //调整该行的链接关系<br/>
}<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while((q!=NULL) && (q->row <i)) <br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if(p==NULL)<br/>
{ //如果为第一个节点<br/>
s->down = pChead [j]; //就把地址存入该列头节点
<br/>
pChead [j] =s;<br/>
}<br/>
else<br/>
{ //如果不是第一个节点<br/>
s->down =q; //调整该列的链接关系<br/>
p->down =s;<br/>
}<br/>
}<br/>
}<br/>
/**********************************************************/<br/>
/* 改变指定位置的元素 *<br/>
/*
*<br/>
/* i,j分别为行列下标 *
<br/>
/**********************************************************/<br/>
void CSparseMatrix::ChangeNodeValue(int i,int j,double value)<br/>
{<br/>
if(i <= 0 || i>GetRow () ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(1); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(2); <br/>
}
MatrixNode *q,*p;<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j)) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j)) <br/>
{<br/>
printf("节点不存在!");<br/>
return ;<br/>
}<br/>
q->val =value; //改变节点的值
<br/>
}
/************************************************************/<br/>
/* 给指定位置的元素增加一个值,若该元素为空, *<br/>
/* 则为该元素分配内存并赋值. *<br/>
/* 该函数主要用来形成装配整体结构刚度矩阵 *<br/>
/* i, j分别为行列下标 *
<br/>
/************************************************************/<br/>
void CSparseMatrix::AddNodeValue (int i, int j, double value)<br/>
{<br/>
if(i <= 0 || i>GetRow () ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(1); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(2); <br/>
}
MatrixNode *q, *p;<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j)) //定位指定的非零节点<br/>
{
<br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j)) <br/>
{<br/>
InsertNode(i, j, value); //若该元素为空, 则为该元素分配内存并赋值<br/>
}<br/>
else<br/>
{<br/>
q->val += value; //增加节点的值
<br/>
}
}
<br/>
/********************************************************/<br/>
/* 删除指定位置的元素 *
<br/>
/*
*<br/>
/* i,j分别为行列下标 *<br/>
/********************************************************/<br/>
void CSparseMatrix::RemoveNode (int i, int j)<br/>
{<br/>
if(i <= 0 || i>GetRow() ) <br/>
{ <br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q= pRhead ;<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->right ;<br/>
};
if(q==NULL || q->col >j )
<br/>
return;<br/>
else <br/>
{<br/>
if(p==NULL) //重新设定行的链接关系<br/>
pRhead =q->right ;<br/>
else p->right =q->right ;<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while(q->row <i) //定位指定的非零节点,<br/>
{ //q指向被删除的节点<br/>
p=q;<br/>
q=q->down ;<br/>
<br/>
};<br/>
if(p==NULL) pChead [j]=q->down ; //重新设定列的链接关系<br/>
else p->down =q->down ;<br/>
delete q;<br/>
DecreaseNode();<br/>
}<br/>
delete p;<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 删除矩阵中的所有元素,释放内存 *<br/>
/*
*<br/>
/********************************************************/<br/>
void CSparseMatrix:elAllNode ()<br/>
{ <br/>
int i;<br/>
if(nNumOfNode==0) return ;<br/>
MatrixNode *q,*p;<br/>
/**/<br/>
for(i=1;i<GetRow()+1;i++) //该for循环用于从每行中删除非零节点<br/>
{ <br/>
p=q=pRhead;<br/>
if(!q)continue; //该行无元素,结束该次循环<br/>
while(q)<br/>
{<br/>
p=q->right ; //下一个节点的指针存储在p中<br/>
delete q;<br/>
q=p; //q指向下一个节点<br/>
}
}//i
for( i=1;i<GetRow()+1;i++) <br/>
{//将行指针赋值为空 <br/>
// delete []pRhead;<br/>
pRhead =NULL; <br/>
}<br/>
// delete []pRhead;<br/>
// pRhead = NULL;<br/>
<br/>
for( i=1;i<GetCol()+1;i++)<br/>
{//将列指针赋值为空 <br/>
// delete []pChead ;<br/>
pChead =NULL;<br/>
}<br/>
// delete []pChead ;<br/>
// pChead = NULL ;
nNumOfNode=0; //数组元素清零
<br/>
delete p, q;<br/>
}
/********************************************************/<br/>
/* 取得指定位置任意的元素 *<br/>
/*
*<br/>
/* i为行下标,j 为列下标 *<br/>
/********************************************************/<br/>
double CSparseMatrix::GetData (int i, int j)<br/>
{ <br/>
if(i <= 0 || i>GetRow() ) //行列参数检查<br/>
{
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 || j>GetCol() ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q=NULL;<br/>
if(i>=j) //如果行数>列数,就从行开始寻找非零节点 <br/>
{<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j) )<br/>
{ <br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL)||(q->col>j)) return 0; //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
else //如果行数<列数,就从列开始寻找非零节点<br/>
{ <br/>
q=pChead [j];<br/>
while((q!=NULL) && (q->row <i))<br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if((q==NULL)||(q->row >i)) return 0; //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
<br/>
}
/********************************************************/<br/>
/*
*<br/>
/* 矩阵转置运算 *<br/>
/*
*<br/>
/********************************************************/<br/>
CSparseMatrix CSparseMatrix::TransposeSMatrix(){<br/>
CSparseMatrix At(this->GetCol() ,this->GetRow ());<br/>
MatrixNode *q;<br/>
double x;<br/>
for(int i=1;i<GetRow()+1;i++)<br/>
{<br/>
q= pRhead ;<br/>
if(!q) continue; //该行无元素,退出此次循环<br/>
for(int j=1;j<GetCol()+1;j++)<br/>
{<br/>
q= pChead [j];<br/>
if(!q) continue; //该列无元素,退出此次循环<br/>
x=GetData(i,j);<br/>
if(x) <br/>
{<br/>
At.InsertNode (j,i,x);<br/>
}<br/>
}//j<br/>
<br/>
}//i<br/>
return At;<br/>
}
CSparseMatrix::~CSparseMatrix ()<br/>
{<br/>
if(nNumOfNode==0) return ;<br/>
MatrixNode *q,*p;<br/>
for(int i=1;i<GetRow()+1;i++) //该for循环用于从每行中删除非零节点<br/>
{ <br/>
p=q=pRhead;<br/>
<br/>
while(q)<br/>
{<br/>
p=q->right ; //下一个节点的指针存储在p中<br/>
delete q;<br/>
q=p; //q指向下一个节点<br/>
}
}//i<br/>
nNumOfNode=0;<br/>
delete []pRhead; //删除行,列头节点<br/>
delete []pChead;
}
double & CSparseMatrix::InsertNode(int i,int j)<br/>
{<br/>
if(i < 0 || i>GetRow ()+1 ) //参数检查<br/>
{<br/>
printf("传入的行参数错误!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j < 0 || j>GetCol()+1 )<br/>
{ <br/>
<br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
MatrixNode *q,*p,*s;<br/>
p=NULL;<br/>
q= pRhead ;
<br/>
<br/>
while(q!=NULL && q->col <j) //定位指定的非零节点,<br/>
{ //q指向被增加的节点前一位 <br/>
p=q; q=q->right ;<br/>
};<br/>
if((q==NULL) || (q->col >j))<br/>
{<br/>
s=new MatrixNode; //增加节点<br/>
IncreaseNode();<br/>
s->row=i; //为节点赋置<br/>
s->col =j;<br/>
s->val =0;<br/>
if(p==NULL) //如果为第一个节点<br/>
{ //就把地址存入该行头节点
<br/>
s->right = pRhead ; <br/>
pRhead =s;<br/>
}<br/>
else <br/>
{<br/>
s->right =q; //如果不是第一个节点<br/>
p->right =s; //调整该行的链接关系<br/>
}<br/>
p=NULL;<br/>
q= pChead [j];<br/>
while((q!=NULL) && (q->row <i)) <br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if(p==NULL)<br/>
{ //如果为第一个节点<br/>
s->down = pChead [j]; //就把地址存入该列头节点
<br/>
pChead [j] =s;<br/>
}<br/>
else<br/>
{ //如果不是第一个节点<br/>
s->down =q; //调整该列的链接关系<br/>
p->down =s;<br/>
}<br/>
}<br/>
return s->val;<br/>
}
<br/>
double & CSparseMatrix:perator()(int i, int j)<br/>
{<br/>
if(i <= 0 ) //行列参数检查<br/>
{ <br/>
printf("传入的行参数错误----!");<br/>
exit(0); <br/>
} <br/>
<br/>
if(j <= 0 ) <br/>
{ <br/>
printf("传入的列参数错误!");<br/>
exit(0); <br/>
}
if(i>GetRow() ) //行列参数检查<br/>
{ <br/>
SetRow(i);<br/>
} <br/>
<br/>
if(j>GetCol() ) <br/>
{ <br/>
SetCol(j);<br/>
}
<br/>
MatrixNode *q,*p;<br/>
p=NULL;<br/>
q=NULL;<br/>
if(i>=j) //如果行数>列数,就从行开始寻找非零节点 <br/>
{<br/>
q= pRhead ;<br/>
while((q!=NULL) && (q->col <j) )<br/>
{ <br/>
p=q;<br/>
q=q->right ;<br/>
};<br/>
if((q==NULL)||(q->col>j)) return InsertNode(i, j); //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
else //如果行数<列数,就从列开始寻找非零节点<br/>
{ <br/>
q=pChead [j];<br/>
while((q!=NULL) && (q->row <i))<br/>
{<br/>
p=q;<br/>
q=q->down ;<br/>
};<br/>
if((q==NULL)||(q->row >i)) return InsertNode(i, j); //没有找到指定节点返回0<br/>
return q->val ;<br/>
}<br/>
p=NULL;<br/>
q=NULL;<br/>
delete []q; //删除行,列头节点<br/>
delete []p;
}
/*<br/>
void InvertMatrix(CSparseMatrix &TM)<br/>
{<br/>
int i, j, n, k;<br/>
double temp;<br/>
<br/>
n = TM.GetCol();<br/>
<br/>
CSparseMatrix a(n, n);<br/>
CSparseMatrix b(n, n);<br/>
CSparseMatrix c(n, n);<br/>
<br/>
}
*/
View the full article