改进08年曾经编过的STL风格的十字链表程序。
二维循环式
1,每个节点有right和down指针。
2,每一行的最后一个元素的right指针指向下一个有效行(不一定是下一行)的第一个元素。
3,每一列的最后一个元素的down指针指向下一个有效列(不一定是下一列)的第一个元素。
4,注意
第一个元素不一定就是左上角,DOWN和RIGHT遍历的第一个元素也可以不同。
//矩阵:
0 1 0 0 0
0 0 0 0 0
3 0 4 0 0
0 5 0 0 0
DOWN:{3}, {1,5}, {4}
RIGHT: {1}, {3,4}, {5}
最后一个元素不一定就是右下角,按照right遍历和down遍历最后一个元素不同。
//矩阵:
0 1 0 0 0
0 0 0 0 0
0 3 4 0 0
0 5 0 0 0
所以迭代器构造的时候必须指定类型:DOWN / RIGHT
矩阵举例分析
0 1 0 0 0
0 0 0 0 0
0 3 4 0 0
0 5 0 0 0
存储结构图:
图 - 1
如图-1,黑色结点HNode为头结点,HNode的right指向第一个有效行的首元素,down指针指向第一个有效列的首元素。
两种颜色的线条,橙色线条表示right指针,蓝色线条表示down指针。
1)每一行最后一个元素的right指针指向下一个有效行第一个元素,
图-1按照right指针遍历的序列为:{1}, {3, 4}, {5} 其中大括号内为同一行元素。
一共三行,第一行最后一个结点1的right指向3结点;第二行最后一个结点4的right指向5;5结点为right遍历的最后一个元素,所以第三行最后一个结点5的right指向了HNode结点,图中有橙色的虚线表示。
STL风格的迭代器设计都是左闭右开,行遍历的伪代码如下:
Iterator<int, RIGHT> it = begin( OList::Node_1 ); it != end( OList::HNode ); ++it );
//do_some_stuff()
迭代器的第一个模板参数为OList存储的数据类型,第二个模板参数为迭代器遍历方式,缺省参数为RIGHT。
2)每一列最后一个元素的down指针指向下一个有效列第一个元素,
图-1按照down指针遍历的序列为:{1,3,5}, {4} 其中大括号内为同一列元素。
一共两列,第一列最后一个结点5的down指针指向4结点。4结点为down遍历的最后一个元素,所以第二列最后一个结点4的down指向了HNode结点。图中有蓝色的虚线表示。
STL风格的迭代器设计都是左闭右开,列遍历的伪代码如下:
Iterator<int, DOWN> it = begin( OList::Node_1 ); it != end( OList::HNode ); ++it );
//do_some_stuff()
迭代器的第一个模板参数为OList存储的数据类型,第二个模板参数为迭代器遍历方式,缺省参数为RIGHT。
总结:
这种存储方式,方便迭代器的设计但是丢失了原稀疏矩阵的行列,元素的位置信息。
行列矩阵式存储
1, 增加行列的头结点:
行头结点:Node* m_pRowHead [ m_RowSize ];
列头结点:Node* m_pColHead[ m_ColSize ];
如果row_idx行全为0,则 m_pRowHead[ row_idx ] = NULL;
2,增加两个行遍历和列遍历的尾结点:rowCapNode, colCapNode,主要是设计迭代器需要。
3,每一行的最后一个结点m_pRight为NULL,最后一行最后一个元素m_pRight指向rowCapNode。
4,每一列的最后一个结点m_pDown为NULL,最后一列最后一个元素m_pDown指向colCapNode。
//矩阵:
0 1 0 0 0
0 0 0 0 0
3 0 4 0 0
0 5 0 0 0
存储结构如图-2:
行遍历:{1}, {3, 4}, {5}, {rowCapNode}
列遍历:{1,3,5}, {4}, {colCapNode}
OrthoList<T>的实现如下:实现了两种const iterator:row, col
#include <iostream>
#include <assert.h>
#define SAFE_DELETE(p) {if(p){delete p; p=NULL;}}
#define ENUM enum
#define CONST const
#define VOID void
#define BOOL bool
#define INLINE inline
#define ASSERT assert
template<class ListDataType> class OrthoList;
template<class ListDataType> class ConstRowIter;
template<class ListDataType> class ConstColIter;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//十字链表结点类的定义
template<class NodeDataType>
class OLNode
{
//申明友元类
friend class ConstRowIter<NodeDataType>;
friend class ConstColIter<NodeDataType>;
friend class OrthoList<NodeDataType>;
public:
OLNode(size_t iPos=0, size_t jPos=0, NodeDataType elem=0)
:m_wRowPos(iPos), m_wColPos(jPos), m_Elem(elem),
m_pRight(NULL), m_pDown(NULL)
{}
OLNode(CONST OLNode<NodeDataType>& node)
:m_wRowPos(node.m_wRowPos), m_wColPos(node.m_wColPos),
m_Elem(node.m_Elem),
m_pRight(NULL), m_pDown(NULL)
{}
~OLNode()
{}
size_t GetRowPos() CONST{ return m_wRowPos; }
size_t GetColPos() CONST{ return m_wColPos; }
NodeDataType GetElemData()CONST {return m_Elem; }
OLNode<NodeDataType>* GetDownPtr()CONST {return m_pDown;}
OLNode<NodeDataType>* GetRightPtr()CONST {return m_pRight;}
VOID SetElemData(NodeDataType val){m_Elem=val;};
private:
size_t m_wRowPos;
size_t m_wColPos;
NodeDataType m_Elem;
OLNode<NodeDataType>* m_pRight;
OLNode<NodeDataType>* m_pDown;
};
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//十字链表的定义
//只是单纯的数据结构
template<class ListDataType>
class OrthoList
{
friend class ConstRowIter<ListDataType>;
friend class ConstColIter<ListDataType>;
public:
OrthoList();
OrthoList(size_t rowNum, size_t collNum);
OrthoList(CONST ListDataType* buffer, size_t row, size_t coll); //一维数组
OrthoList(CONST OrthoList<ListDataType>& cMatrix);
~OrthoList();
public:
typedef OLNode<ListDataType>* OLink;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class ConstRowIter
{
public:
typedef ListDataType value_type;
typedef OLNode<value_type> node_type;
typedef OrthoList<value_type> list_type;
// 初始化迭代器,记录初始化行列
ConstRowIter(){};
// 找到olist的第一个有效行首元素
ConstRowIter(OLink node, const list_type * olist)
: _current(node),
m_iNum(0),
m_pOList(olist)
{
m_iCurrentRow = m_pOList->availableRow[0]; //minRow
}
~ConstRowIter(){};
// 遍历链表方式:只能行优先
ConstRowIter& operator++()
{
m_iNum++;
_current = _current->m_pRight;
AdjustRowImpl__();
return *this;
}
// OListIter& operator++(int)
// temporary object reference
const ConstRowIter operator++(int)
{
ConstRowIter tem = *this;
++*this;
return tem;
}
// 一般的遍历方式
node_type& operator*() const
{
return *_current;
}
node_type* operator->() const
{
return _current;
}
node_type* get() const
{
return _current;
}
// 判断结束
bool valid() const
{
return m_iNum!=m_pOList->GetTotalSize();
}
// 重载二目运算符
BOOL operator ==(const ConstRowIter& rhs) const{return _current==rhs._current;};
BOOL operator !=(const ConstRowIter& rhs) const{return _current!=rhs._current;};
private:
inline VOID AdjustRowImpl__()
{
while(!_current)
{
// 调节_current指向下一个有效行第一个元素
if(++m_iCurrentRow < m_pOList->m_wRowSize)
_current=m_pOList->m_pRowHead[m_iCurrentRow];
}
}
const list_type* m_pOList;
node_type* _current; //内部链表元素遍历器
size_t m_iCurrentRow;
size_t m_iNum;
};
typedef ConstRowIter const_row_iterator;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
class ConstColIter
{
public:
typedef ListDataType value_type;
typedef OLNode<value_type> node_type;
typedef OrthoList<value_type> list_type;
/*
* 初始化迭代器,记录初始化行列
*/
ConstColIter(){};
// 找到olist的第一个有效行首元素
ConstColIter(OLink node, const list_type* olist)
: _current(node),
m_iNum(0),
m_pOList(olist)
{
m_iCurrentCol = m_pOList->availableCol[0]; //minCol
}
~ConstColIter(){};
// 遍历链表方式:只能行优先
ConstColIter& operator++()
{
m_iNum++;
_current = _current->m_pDown;
AdjustColImpl__();
return *this;
}
// OListIter& operator++(int)
// temporary object reference
const ConstColIter operator++(int)
{
ConstColIter tem = *this;
++*this;
return tem;
}
// 一般的遍历方式
node_type& operator*() const
{
return *_current;
}
node_type* operator->() const
{
return _current;
}
node_type* get() const
{
return _current;
}
// 判断结束
bool valid() const
{
return m_iNum!=m_pOList->GetTotalSize();
}
// 重载二目运算符
BOOL operator ==(const ConstColIter& rhs) const{return _current==rhs._current;};
BOOL operator !=(const ConstColIter& rhs) const{return _current!=rhs._current;};
private:
VOID AdjustColImpl__()
{
while(!_current)
{
// 调节_current指向下一个有效行第一个元素
if(++m_iCurrentCol < m_pOList->m_wColSize)
_current=m_pOList->m_pColHead[m_iCurrentCol];
}
}
const list_type* m_pOList;
node_type* _current; //内部链表元素遍历器
size_t m_iCurrentCol;
size_t m_iNum;
};
typedef ConstColIter const_col_iterator;
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
const_row_iterator rBegin() const
{
return (const_row_iterator(m_pRowHead[ availableRow[0] ], this));
//return row_iterator(GetFirstNodeByRow(),this);
}
const_row_iterator rEnd() const
{
return (const_row_iterator(rowCapNode, this));
}
const_col_iterator cBegin() const
{
return (const_col_iterator(m_pColHead[ availableCol[0] ], this));
}
const_col_iterator cEnd() const
{
return (const_col_iterator(colCapNode, this));
}
size_t GetRowSize() CONST{ return m_wRowSize; }
size_t GetColSize() CONST{ return m_wColSize; }
size_t GetTotalSize() CONST{ return m_wTotalSize;}
CONST OLink GetRow(size_t row) CONST {return m_pRowHead[row];}
CONST OLink GetColl(size_t col) CONST {return m_pColHead[col];}
CONST OLink GetFirstNodeByRow() CONST;
CONST OLink GetFirstNodeByCol() CONST;
VOID InsertNode(OLink& node); //创建十字链表
VOID InsertNode(size_t iPos, size_t jPos, ListDataType elem);
VOID InsertInRow(OLink& node); //插入元素到行
VOID InsertInCol(OLink& node); //插入元素到列
VOID CreateListHeads(); //创建行列头结点
VOID Free(); //释放十字链表
//深拷贝
template<class ListDataType>
friend VOID Copy(OrthoList<ListDataType>& src, CONST OrthoList<ListDataType>& dest);
private:
OLink* m_pRowHead;
OLink* m_pColHead;
size_t m_wRowSize;
size_t m_wColSize;
size_t m_wTotalSize;
// 只是为了设计迭代器方便
// availableRow[0] 当前的第一个有效行
// availableRow[1] 当前最后一个有效行
size_t availableRow[2]; //min max
size_t availableCol[2]; //min max
OLink rowCapNode;
OLink colCapNode;
};
OrthoList<T>的实现,注意跟定义放在一个头文件中:
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//OrthoList类的实现
template<class ListDataType>
OrthoList<ListDataType>::OrthoList()
:m_wRowSize(0), m_wColSize(0), m_wTotalSize(0),
m_pRowHead(NULL), m_pColHead(NULL)
{}
template<class ListDataType>
OrthoList<ListDataType>::OrthoList(CONST ListDataType* buffer, size_t row, size_t coll)
:m_wRowSize(row), m_wTotalSize(0), m_wColSize(coll),
m_pRowHead(NULL), m_pColHead(NULL)
{
CreateListHeads();
for(size_t i=0; i<row*coll; i++)
if(buffer[i])
InsertNode(i/coll, i%coll, buffer[i]);
}
template<class ListDataType>
OrthoList<ListDataType>::OrthoList(size_t rowNum, size_t collNum)
:m_wRowSize(rowNum), m_wColSize(collNum), m_wTotalSize(0),
m_pRowHead(NULL), m_pColHead(NULL)
{
CreateListHeads();
}
template<class ListDataType>
OrthoList<ListDataType>::OrthoList(CONST OrthoList<ListDataType>& cMatrix)
:m_wTotalSize(0),
m_pRowHead(NULL), m_pColHead(NULL)
{
Copy(*this, cMatrix);
}
template<class ListDataType>
OrthoList<ListDataType>::~OrthoList()
{
Free();
}
template<class ListDataType>
VOID OrthoList<ListDataType>::Free()
{
//列优先释放内存;
for (size_t i=0; i<m_wColSize; i++)
{
OLink tem;
while (m_pColHead[i])
{
tem=m_pColHead[i];
m_pColHead[i]=m_pColHead[i]->m_pDown;
SAFE_DELETE(tem);
// 4/26/2011 RYF
// 这里可以删除colCapNode
}
}
SAFE_DELETE(m_pColHead);
SAFE_DELETE(m_pRowHead);
// 4/26/2011 RYF
SAFE_DELETE(rowCapNode);
}
template<class ListDataType>
VOID OrthoList<ListDataType>::CreateListHeads()
{
//没有异常处理
m_pRowHead=new OLink[m_wRowSize]; //创建行头指针表;
m_pColHead=new OLink[m_wColSize]; //创建列头指针表;
for (size_t i=0; i<m_wRowSize; i++)
m_pRowHead[i]=NULL;
for (size_t i=0; i<m_wColSize; i++)
m_pColHead[i]=NULL;
// 4/26/2011 RYF
availableRow[0] = m_wRowSize-1;
availableRow[1] = 0;
availableCol[0] = m_wColSize-1;
availableCol[1] = 0;
rowCapNode = new OLNode<ListDataType>;
colCapNode = new OLNode<ListDataType>;
m_pRowHead[ availableRow[1] ] = rowCapNode;
m_pColHead[ availableCol[1] ] = colCapNode;
}
template<class ListDataType>
CONST typename OrthoList<ListDataType>::OLink
OrthoList<ListDataType>::GetFirstNodeByRow() CONST
{
// return m_pRowHead[ availableRow[0] ];
int i(0);
while(!m_pRowHead[i] && i<m_wRowSize)
i++;
return m_pRowHead[i];
}
template<class ListDataType>
CONST typename OrthoList<ListDataType>::OLink
OrthoList<ListDataType>::GetFirstNodeByCol() CONST
{
int i(0);
while(!m_pColHead[i] && i<m_wColSize)
i++;
return m_pColHead[i];
}
template<class ListDataType>
VOID OrthoList<ListDataType>::InsertNode(OLink& node)
{
ASSERT(node != NULL);
if( !m_pColHead || !m_pRowHead)
CreateListHeads();
m_wTotalSize++;
InsertInRow(node);
InsertInCol(node);
}
template<class ListDataType>
VOID OrthoList<ListDataType>::InsertNode(size_t iPos, size_t jPos, ListDataType elem)
{
OLink node=new OLNode<ListDataType>(iPos, jPos, elem);
InsertNode(node);
}
template<class ListDataType>
VOID OrthoList<ListDataType>::InsertInRow(OLink& node)
{
ASSERT(node != NULL);
size_t i=node->m_wRowPos;
size_t j=node->m_wColPos;
// 4/26/2011 RYF
size_t& minRow = availableRow[0];
size_t& maxRow = availableRow[1];
if ( i<minRow )
minRow = i; //update min row.
if ( i>maxRow ) //update max row
{
// 将node第一次插入i行
// node->m_pRight == m_pRowHead[i] == NULL;
m_pRowHead[i] = node;
// 交换node的right和maxRow行最后一个元素的right指针
// maxRow行没有元素
if (m_pRowHead[maxRow]==rowCapNode)
{
m_pRowHead[maxRow] = NULL;
}
else
{
// maxRow行至少有一个元素,查找maxRow的最后一个元素
OLink bg;
for(bg=m_pRowHead[maxRow]; bg->m_pRight != rowCapNode; bg=bg->m_pRight) ;
bg->m_pRight = NULL;
}
node->m_pRight = rowCapNode;
// 更新maxRow
maxRow = i;
}
else if( i==maxRow ) //插入元素在maxRow行
{
// 直接插到行首
if (m_pRowHead[i]==rowCapNode || j<m_pRowHead[i]->m_wColPos)
{
node->m_pRight = m_pRowHead[i];
m_pRowHead[i] = node;
}
else //在行中查找插入位置,注意循环结束条件!
{
OLink bg;
for(bg=m_pRowHead[i];
bg->m_pRight != rowCapNode && bg->m_pRight->m_wColPos<j;
bg=bg->m_pRight)
;
// 将node插到bg后面
node->m_pRight=bg->m_pRight; bg->m_pRight=node;
}
} // 4/26/2011 RYF
else // i < maxRow
{
//直接插入:空,或者列座标大于此行链表中的最大列座标
//同一行里面,链表按照列的座标排序,
//行第一个元素(0,2),插入(0,1)时。
if( m_pRowHead[i]==NULL || m_pRowHead[i]->m_wColPos>j )
{
node->m_pRight=m_pRowHead[i];
m_pRowHead[i]=node;
}
else //查寻在行表中的插入位置:
{
OLink bg;
// 行第一个元素(0,2),插入(0,3)时。
for(bg=m_pRowHead[i]; bg->m_pRight && bg->m_pRight->m_wColPos<j; bg=bg->m_pRight) ;
node->m_pRight=bg->m_pRight; bg->m_pRight=node;
} //完成行插入。
}
}
template<class ListDataType>
VOID OrthoList<ListDataType>::InsertInCol(OLink& node)
{
ASSERT(node != NULL);
size_t i=node->m_wRowPos;
size_t j=node->m_wColPos;
// 4/26/2011 RYF
size_t& minCol = availableCol[0];
size_t& maxCol = availableCol[1];
if ( j<minCol )
minCol = j; //update min row.
if ( j>maxCol ) //update max row
{
// 将node第一次插入j列
m_pColHead[j] = node;
// 交换node的down和maxCol列最后一个元素的down指针
// maxCol列没有元素
if (m_pColHead[maxCol]==colCapNode)
{
m_pColHead[maxCol] = NULL;
}
else
{
// maxCol列至少有一个元素,查找maxCol列的最后一个元素
OLink bg;
for(bg=m_pColHead[maxCol]; bg->m_pDown != colCapNode; bg=bg->m_pDown) ;
bg->m_pDown = NULL;
}
node->m_pDown = colCapNode;
// 更新maxCol
maxCol = j;
}
else if( j==maxCol ) //插入元素在maxCol列
{
// 直接插到列首
if (m_pColHead[j]==colCapNode || i<m_pColHead[j]->m_wRowPos)
{
node->m_pDown = m_pColHead[j];
m_pColHead[j] = node;
}
else //在列中查找插入位置,注意循环结束条件!
{
OLink bg;
for(bg=m_pColHead[j];
bg->m_pDown != colCapNode && bg->m_pDown->m_wRowPos<i;
bg=bg->m_pDown)
;
// 将node插到bg后面
node->m_pDown=bg->m_pDown; bg->m_pDown=node;
}
} // 4/26/2011 RYF
else // j < maxCol
{
//直接插入:空,或者行座标大于此列链表中的最大行座标
//同一列里面,链表按照行的座标排序,
if( m_pColHead[j]==NULL || m_pColHead[j]->m_wRowPos>i )
{
node->m_pDown=m_pColHead[j];
m_pColHead[j]=node;
}
else //查寻在列表中的插入位置:
{
OLink bg;
for(bg=m_pColHead[j]; bg->m_pDown && bg->m_pDown->m_wRowPos<i; bg=bg->m_pDown) ;
node->m_pDown=bg->m_pDown; bg->m_pDown=node;
} //完成列插入。
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
}
基于迭代器的功能函数设计:copy和print
// 使用迭代器输出
template<class ListDataType>
VOID PrintMatrixByRow(CONST OrthoList<ListDataType>& olist)
{
size_t last_row(0), last_col(-1);
bool isNewRow(false);
OrthoList<ListDataType>::const_row_iterator lastIter;
// 换行情形
for (OrthoList<ListDataType>::const_row_iterator iter = olist.rBegin();
iter != olist.rEnd();
iter++)
{
size_t cur_row = iter->GetRowPos();
size_t cur_col = iter->GetColPos();
if (last_row<cur_row)
isNewRow = true;
//空行的特殊处理: 输出last_row和cur_row
if (isNewRow)
{
// 上一行的尾部充0
for (size_t c(last_col+1); c<olist.GetColSize(); c++)
{
std::cout.width(6);
std::cout << 0 << " ";
}
std::cout << "/n";
// 填充中间的空白行
for (size_t r=last_row+1; r<cur_row; r++)
{
for (size_t c(0); c<olist.GetColSize(); c++)
{
std::cout.width(6);
std::cout << 0 << " ";
}
std::cout << "/n";
}
last_col = 0; // 从新一行的0列开始
isNewRow = false;
//新一行首部元素充0
for (size_t c(last_col); c<cur_col; c++)
{
std::cout.width(6);
std::cout << 0 << " ";
}
}
else
{
//行内元素间充0
for (size_t c(last_col); c<cur_col-1; c++)
{
std::cout.width(6);
std::cout << 0 << " ";
}
}
//输出元素
std::cout.width(6);
std::cout << iter->GetElemData() << " ";
// 记录
last_row = cur_row;
last_col = cur_col;
lastIter = iter;
}
// 最后一行尾部充0
for (size_t c = lastIter->GetColPos()+1; c<olist.GetColSize(); c++)
{
std::cout.width(6);
std::cout << 0 << " ";
} std::cout << "/n";
}
// 根据src的内容拷贝构造dest十字链表
template<class ListDataType>
VOID Copy(OrthoList<ListDataType>& src,
CONST OrthoList<ListDataType>& dest)
{
src.m_wColSize = dest.m_wColSize;
src.m_wRowSize = dest.m_wRowSize;
src.CreateListHeads();
//按照行优先构造
for(OrthoList<ListDataType>::const_row_iterator iter = dest.rBegin();
iter != dest.rEnd();
++iter)
src.InsertNode( iter->GetRowPos(), iter->GetColPos(),
iter->GetElemData());
}
测试:
#include "stdafx.h"
#ifndef ORTHOLISTTEST_H
#define ORTHOLISTTEST_H
#include "OrthoList.hpp"
CONST int SparseMat[]=
{
1, 0,0, 0,0, 0,0,
0,12,9, 0,0, 0,0,
3,0,0, 0,0,14,0,
0, 0,24,0,0, 0,0,
0,18,0, 0,0, 0,0,
15,0,0, -7,0,0,0,
0,1,0, 0,0, 0,0
};
class OrthoListTest
{
public:
~OrthoListTest()
{
DestroyOList();
}
//Matrix:6×7
static CONST int Row=7;
static CONST int Coll=7;
static OrthoList<int>* OList;
static VOID CreateOList()
{
/*
* 测试十字链表
*/
std::cout<<std::endl<<"CreateOList"<<std::endl;
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
OList = new OrthoList<int>(Row, Coll);
for(int i=0; i<sizeof(SparseMat)/sizeof(SparseMat[0]); i++)
if(SparseMat[i])
OList->InsertNode(i/Coll, i%Coll, SparseMat[i]);
PrintMatrixByRow(*OList);
// PrintMatrixInLine(*OList);
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
}
static VOID OLIterTest()
{
/*
* 测试迭代器:OListIter://按照行优先遍历
*/
std::cout<<std::endl<<"OLIterTest"<<std::endl;
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
for(OrthoList<int>::const_row_iterator iter=OList->rBegin();
iter!=OList->rEnd();
++iter)
{
std::cout << "( " << iter->GetRowPos() << " , " << iter->GetColPos();
std::cout << " , " << iter->GetElemData() << " )/n";
}
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
for(OrthoList<int>::const_col_iterator iter=OList->cBegin(); iter!=OList->cEnd(); ++iter)
{
std::cout << "( " << iter->GetRowPos() << " , " << iter->GetColPos();
std::cout << " , " << iter->GetElemData() << " )/n";
}
std::cout<<"/*----------------------------------------------------------*/"<<std::endl;
}
static VOID DestroyOList()
{
if (OList)
delete OList;
OList = 0;
}
static VOID BeginTest()
{
CreateOList();
OLIterTest();
DestroyOList(); // RYF 2011/4/25
}
};
//静态成员申明
OrthoList<int>* OrthoListTest::OList;
#endif /*SPARSETEST_H*/