C++实现的十字链表:容器和迭代器

改进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:{1,3,5},     {4}
RIGHT: {1},{3,4}, {5}

 

所以迭代器构造的时候必须指定类型: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*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章