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*/

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