一個(gè)學(xué)期課程結(jié)束,接著去公司改bug。以前做的一個(gè)網(wǎng)格控件老是出問題,于是下狠心重新實(shí)現(xiàn)一個(gè)!
準(zhǔn)備實(shí)現(xiàn)一個(gè)網(wǎng)格數(shù)據(jù)結(jié)構(gòu),來存儲網(wǎng)格控件數(shù)據(jù)。為了以后也可以使用,寫了一個(gè)模板類,基本思想是寫3個(gè)類:
/********************************************************************
created: 2006/01/12
created: 12:1:2006 14:30
filename: E:\MyProject\WLWLib\WLWGrid\WLWGrid.h
file path: E:\MyProject\WLWLib\WLWGrid
file base: WLWGrid
file ext: h
author: 萬連文
purpose: 為了存儲二維網(wǎng)格m×n數(shù)據(jù),實(shí)現(xiàn)插入刪除訪問
用鏈表實(shí)現(xiàn),適合大數(shù)據(jù)量(非海量數(shù)據(jù))頻繁插入刪除使用
不適合稀疏矩陣使用,不適合海量數(shù)據(jù),因?yàn)橄∈杈仃嚂速M(fèi)
很多單元格,海量數(shù)據(jù)會浪費(fèi)很多單元格里面的指針
*********************************************************************/
// 網(wǎng)格單元類,存儲數(shù)據(jù),記錄方位
template<class T>
class WLWGridCell
{
public:
WLWGridCell(T xData, WLWGridCell* pLeft=0, WLWGridCell* pUp=0, WLWGridCell* pRight=0, WLWGridCell* pDown=0)
{
SetData(xData);
SetLeft(pLeft);
SetRight(pRight);
SetUp(pUp);
SetDown(pDown);
m_lReserve = 0;
}
~WLWGridCell()
{
SetLeft(0);
SetRight(0);
SetUp(0);
SetDown(0);
}
// 設(shè)置數(shù)據(jù)
void SetData(T xData);
// 獲得數(shù)據(jù)
T GetData();
// 設(shè)置保留數(shù)據(jù)
void SetReserve(long lReserve);
// 獲得保數(shù)據(jù)
long GetReserve();
// 設(shè)置上方單元
void SetUp(WLWGridCell* pUp);
// 獲得上方單元
WLWGridCell* GetUp();
// 設(shè)置下方單元
void SetDown(WLWGridCell* pDown);
// 獲得下方單元
WLWGridCell* GetDown();
// 設(shè)置左方單元
void SetLeft(WLWGridCell* pLeft);
// 獲得左方單元
WLWGridCell* GetLeft();
// 設(shè)置右方單元
void SetRight(WLWGridCell* pRight);
// 獲得右方單元
WLWGridCell* GetRight();
private:
WLWGridCell* m_pUp; // 上方單元
WLWGridCell* m_pDown; // 下方單元
WLWGridCell* m_pLeft; // 左方單元
WLWGridCell* m_pRight; // 右方單元
T m_xData; // 存儲數(shù)據(jù)
long m_lReserve; // 保留數(shù)據(jù)
};
// 網(wǎng)格行類,存儲一行數(shù)據(jù)
template<class T>
class WLWGridRow
{
public:
WLWGridRow(WLWGridRow<T>* pUp=0, WLWGridRow<T>* pDown=0)
{
m_pHead = 0;
m_pTail = 0;
m_pCurr = 0;
m_lReserve = 0;
m_pUp = pUp;
m_pDown = pDown;
}
~WLWGridRow()
{
// 銷毀所有網(wǎng)格
Empty();
}
// 獲得當(dāng)前的行頭指針
WLWGridCell<T>* GetHead();
// 獲得當(dāng)前的行尾指針
WLWGridCell<T>* GetTail();
// 設(shè)置上一行
void SetUpRow(WLWGridRow<T>* pUp);
// 獲得上一行
WLWGridRow<T>* GetUpRow();
// 設(shè)置下一行
void SetDownRow(WLWGridRow<T>* pDown);
// 獲得下一行
WLWGridRow<T>* GetDownRow();
// 獲得當(dāng)前的游標(biāo)指針
WLWGridCell<T>* GetCurrent();
// 按照索引獲得單元格
WLWGridCell<T>* GetCellByIndex(int iIndex);
// 按照單元格獲得索引,失敗返回-1
int GetIndexByCell(WLWGridCell<T>* pCell);
// 當(dāng)前指針右移
void MoveNext();
// 當(dāng)前指針左移
void MoveBack();
// 當(dāng)前指針行頭
void MoveHead();
// 當(dāng)前指針行尾
void MoveTail();
// 判斷是否有下一個(gè)
bool HasNext();
// 判斷是否有上一個(gè)
bool HasBack();
// 判斷是否為空
bool IsEmpty();
// 清空行數(shù)據(jù)
void Empty();
// 設(shè)置保留數(shù)據(jù)
void SetReserve(long lReserve);
// 獲得保數(shù)據(jù)
long GetReserve();
// 添加一個(gè)單元格,bRight=true表示添加在pos后面
// 可能修改m_pHead、m_pTail
// 返回<0表示添加失敗;=0表示已存在;>0表示成功
int AddCell(WLWGridCell<T>* pCell, WLWGridCell<T>* pPos, bool bRight=true);
// 添加一個(gè)單元格,iIndex是索引,bRight=true表示添加在iIndex后面
// 可能修改m_pHead、m_pTail
// 返回<0表示添加失敗;=0表示已存在;>0表示成功
int AddCell(WLWGridCell<T>* pCell, int iIndex, bool bRight=true);
// 刪除指定單元格,可能修改m_pHead、m_pTail、m_pCurr
void DelCell(WLWGridCell<T>* pCell);
// 刪除指定單元格,iIndex是索引,表示單元格的位置
// 可能修改m_pHead、m_pTail、m_pCurr
void DelCell(int iIndex);
// 查找指定值的單元格,失敗返回-1,否則返回索引
int Find(T x);
// 重載[]運(yùn)算符
WLWGridCell<T>* operator[](int iIndex);
private:
WLWGridCell<T>* m_pHead; // 記錄一行的頭
WLWGridCell<T>* m_pTail; // 記錄一行的尾
WLWGridCell<T>* m_pCurr; // 當(dāng)前游標(biāo)位置,遍歷的時(shí)候使用
WLWGridRow<T>* m_pUp; //上一行
WLWGridRow<T>* m_pDown; //下一行
long m_lReserve; // 保留數(shù)據(jù)
};
// 網(wǎng)格類,實(shí)現(xiàn)二維表格結(jié)構(gòu)
template<class T>
class WLWGrid
{
public:
WLWGrid()
{
m_pHead = 0;
}
~WLWGrid()
{
Empty();
}
// 獲得頭行
WLWGridRow<T>* GetHead();
// 獲得列數(shù)
int GetCols();
// 獲得行數(shù)
int GetRows();
// 判斷是否為空
bool IsEmpty();
// 清空表格
void Empty();
// 按照索引獲得行
WLWGridRow<T>* GetRowByIndex(int iIndex);
// 按照行獲得索引,失敗返回-1
int GetIndexByRow(WLWGridRow<T>* pRow);
// 指定位置添加一行,bRight=true表示添加在pos后面
// 可能修改m_pHead
// 注意行的單元格數(shù)目必須等于Grid的列數(shù),否則不添加
// 返回<0添加失敗,0已存在,>0添加成功
int AddRow(WLWGridRow<T>* pRow, WLWGridRow<T>* pPos, bool bDown=true);
// 指定位置添加一行,iIndex是索引,bRight=true表示添加在pos后面
// 可能修改m_pHead
// 注意行的單元格數(shù)目必須等于Grid的列數(shù),否則不添加
// 返回<0添加失敗,0已存在,>0添加成功
int AddRow(WLWGridRow<T>* pRow, int iIndex, bool bDown=true);
// 指定位置添加值為xData的一行,bRight=true表示添加在pos后面
// 可能修改m_pHead
void AddRow(T xData, WLWGridRow<T>* pPos, bool bDown=true);
// 指定位置添加值為xData的一行,iIndex是索引,bRight=true表示添加在pos后面
// 可能修改m_pHead
void AddRow(T xData, int iIndex, bool bDown=true);
// 刪除指定行,可能修改m_pHead
void DelRow(WLWGridRow<T>* pRow);
// 刪除指定索引的行,可能修改m_pHead
void DelRow(int iIndex);
// 指定位置添加值為xData的一列,bRight表示在iIndex索引右面添加,否則在左面添加
// 添加成功返回true
bool AddCol(T xData, int iIndex, bool bRight=true);
// 刪除下標(biāo)為iIndex的一列
void DelCol(int iIndex);
// 重載[]運(yùn)算符
WLWGridRow<T>* operator[](int iIndex);
private:
WLWGridRow<T>* m_pHead; // 頭行
// 更新行單元格的指針,確保兩行長度一致,否則會導(dǎo)致非預(yù)期結(jié)果(0指針除外)
void UpdateRowCellPtr(WLWGridRow<T>* pUp, WLWGridRow<T>* pDown);
};
化了接近一天時(shí)間寫完,并經(jīng)過簡單測試,沒有發(fā)現(xiàn)內(nèi)存泄漏問題。
看測試截圖 表現(xiàn)網(wǎng)格結(jié)構(gòu)
下載網(wǎng)格數(shù)據(jù)結(jié)構(gòu)及測試代碼
希望大家下載使用,提出建議,報(bào)告bug,最重要是內(nèi)存泄漏問題,謝謝!
posted on 2006-01-13 17:12
萬連文 閱讀(1295)
評論(4) 編輯 收藏 引用 所屬分類:
亂七八糟