• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            萬星星@豌豆莢 歡迎加入我們
            一個吃軟飯的男人!!!!!我只想寫程序####
            微博:http://weibo.com/wanlianwen
            posts - 172,  comments - 1253,  trackbacks - 0

            一個學期課程結束,接著去公司改bug。以前做的一個網格控件老是出問題,于是下狠心重新實現一個!

            準備實現一個網格數據結構,來存儲網格控件數據。為了以后也可以使用,寫了一個模板類,基本思想是寫3個類:

            /********************************************************************
             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: 為了存儲二維網格m×n數據,實現插入刪除訪問
                用鏈表實現,適合大數據量(非海量數據)頻繁插入刪除使用
                不適合稀疏矩陣使用,不適合海量數據,因為稀疏矩陣會浪費
                很多單元格,海量數據會浪費很多單元格里面的指針
            *********************************************************************/

            // 網格單元類,存儲數據,記錄方位
            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);
             }
             // 設置數據
             void   SetData(T xData);

             // 獲得數據
             T    GetData();

             // 設置保留數據
             void   SetReserve(long lReserve);

             // 獲得保數據
             long   GetReserve();
             
             // 設置上方單元
             void   SetUp(WLWGridCell* pUp);

             // 獲得上方單元
             WLWGridCell* GetUp();

             // 設置下方單元
             void   SetDown(WLWGridCell* pDown);

             // 獲得下方單元
             WLWGridCell* GetDown();

             // 設置左方單元
             void   SetLeft(WLWGridCell* pLeft);

             // 獲得左方單元
             WLWGridCell* GetLeft();

             // 設置右方單元
             void   SetRight(WLWGridCell* pRight);

             // 獲得右方單元
             WLWGridCell* GetRight();
            private:
             WLWGridCell* m_pUp;  // 上方單元
             WLWGridCell* m_pDown; // 下方單元
             WLWGridCell* m_pLeft; // 左方單元
             WLWGridCell* m_pRight; // 右方單元

             T    m_xData; // 存儲數據
             long   m_lReserve; // 保留數據
            };

            // 網格行類,存儲一行數據
            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()
             {
              // 銷毀所有網格
              Empty();
             }

             // 獲得當前的行頭指針
             WLWGridCell<T>* GetHead();

             // 獲得當前的行尾指針
             WLWGridCell<T>* GetTail();

             // 設置上一行
             void   SetUpRow(WLWGridRow<T>* pUp);

             // 獲得上一行
             WLWGridRow<T>* GetUpRow();

             // 設置下一行
             void   SetDownRow(WLWGridRow<T>* pDown);

             // 獲得下一行
             WLWGridRow<T>* GetDownRow();

             // 獲得當前的游標指針
             WLWGridCell<T>* GetCurrent();

             // 按照索引獲得單元格
             WLWGridCell<T>* GetCellByIndex(int iIndex);

             // 按照單元格獲得索引,失敗返回-1
             int    GetIndexByCell(WLWGridCell<T>* pCell);

             // 當前指針右移
             void   MoveNext();

             // 當前指針左移
             void   MoveBack();

             // 當前指針行頭
             void   MoveHead();

             // 當前指針行尾
             void   MoveTail();

             // 判斷是否有下一個
             bool   HasNext();

             // 判斷是否有上一個
             bool   HasBack();

             // 判斷是否為空
             bool   IsEmpty();

             // 清空行數據
             void   Empty();

             // 設置保留數據
             void   SetReserve(long lReserve);

             // 獲得保數據
             long   GetReserve();

             // 添加一個單元格,bRight=true表示添加在pos后面
             // 可能修改m_pHead、m_pTail
             // 返回<0表示添加失敗;=0表示已存在;>0表示成功
             int    AddCell(WLWGridCell<T>* pCell, WLWGridCell<T>* pPos, bool bRight=true);
             
             // 添加一個單元格,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);

             // 重載[]運算符
             WLWGridCell<T>* operator[](int iIndex);
            private:
             WLWGridCell<T>* m_pHead; // 記錄一行的頭
             WLWGridCell<T>* m_pTail; // 記錄一行的尾
             WLWGridCell<T>* m_pCurr; // 當前游標位置,遍歷的時候使用

             WLWGridRow<T>* m_pUp;  //上一行
             WLWGridRow<T>* m_pDown; //下一行
             long   m_lReserve; // 保留數據
            };

            // 網格類,實現二維表格結構
            template<class T>
            class WLWGrid
            {
            public:
             WLWGrid()
             {
              m_pHead  = 0;
             }
             ~WLWGrid()
             {
              Empty();
             }
             // 獲得頭行
             WLWGridRow<T>* GetHead();

             // 獲得列數
             int    GetCols();

             // 獲得行數
             int    GetRows();

             // 判斷是否為空
             bool   IsEmpty();

             // 清空表格
             void   Empty();

             // 按照索引獲得行
             WLWGridRow<T>* GetRowByIndex(int iIndex);

             // 按照行獲得索引,失敗返回-1
             int    GetIndexByRow(WLWGridRow<T>* pRow);
             
             // 指定位置添加一行,bRight=true表示添加在pos后面
             // 可能修改m_pHead
             // 注意行的單元格數目必須等于Grid的列數,否則不添加
             // 返回<0添加失敗,0已存在,>0添加成功
             int    AddRow(WLWGridRow<T>* pRow, WLWGridRow<T>* pPos, bool bDown=true);
             
             // 指定位置添加一行,iIndex是索引,bRight=true表示添加在pos后面
             // 可能修改m_pHead
             // 注意行的單元格數目必須等于Grid的列數,否則不添加
             // 返回<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);

             // 刪除下標為iIndex的一列
             void   DelCol(int iIndex);

             // 重載[]運算符
             WLWGridRow<T>* operator[](int iIndex);
            private:
             WLWGridRow<T>* m_pHead; // 頭行

             // 更新行單元格的指針,確保兩行長度一致,否則會導致非預期結果(0指針除外)
             void   UpdateRowCellPtr(WLWGridRow<T>* pUp, WLWGridRow<T>* pDown);
            };

            化了接近一天時間寫完,并經過簡單測試,沒有發現內存泄漏問題。

            看測試截圖  表現網格結構

            下載網格數據結構及測試代碼

            希望大家下載使用,提出建議,報告bug,最重要是內存泄漏問題,謝謝!

            posted on 2006-01-13 17:12 萬連文 閱讀(1295) 評論(4)  編輯 收藏 引用 所屬分類: 亂七八糟

            FeedBack:
            # re: 數據結構之網格實現
            2006-01-16 10:36 | 小明
            意見來了。

            看一個庫的接口好壞,從使用者上看是一個好的角度

            你的測試代碼
            m_aRow = new WLWGridRow<int>();
            m_aRow->AddCell(new WLWGridCell<int>(1), m_aRow->GetTail());
            if(m_aGrid.AddRow(m_aRow, m_aGrid.GetHead()) < 0)


            1.為什么要new WLWGridCell<int>(0)
            這樣是不是更好
            m_aRow->AddCell(1, m_aRow->GetTail());

            2.如果使用者這樣寫
            WLWGridRow<int> wl;
            if(m_aGrid.AddRow(&wl, m_aGrid.GetHead()) < 0)
            程序會崩潰吧,兩次delete,STL容器使用的方法普遍是copy in,copy out,效率是要付出一些,但是很穩定可靠

            如果一定是使用指針傳入,建議可以使用這樣聲明的方式
            Class WLWGrid
            ...
            int AddRow(WLWGridRow<T>* &pRow, WLWGridRow<T>* pPos, bool bDown=true)
            {
            pRow = 0; //avoid delete twice
            }

            WLWGridRow<T>* &pRow聲明成指針引用的形式,表明你是要代替使用者來管理節點類的生命周期

            3.其實使用vector< vector<type*> > 就能很好的實現你的需要,簡單可靠

            4.不要把template的實現放在cpp文件中



              回復  更多評論
              
            # re: 數據結構之網格實現
            2006-01-16 20:26 | 萬連文
            非常感謝批評!!
            對于1建議非常好,當時由于時間以及個人主觀因素沒有實現
            對于2由于現在在公司,沒法看,但是有可能是自己代碼有問題。里面的小技巧很少用,呆會研究一下,謝謝共享技術
            對于3我則不認同,如果vector< vector<type*> >可以方便實現我的需求的話我不會花費那么大代價了。其實一般獲取數據是可以滿足的,但是在插入和刪除數據時會非常麻煩(不在尾部的話)。還考慮到移動數據的原因所以采用鏈表實現,其實可以采用list實現,處于一個想學數據結構的朋友的建議才自己動手的
            對于4其實我是違背了模板的思想,強制把實現放入cpp,可能會誤導他人,當時只是為了玩玩,原以為可以show一下,沒想到貽笑大方了
            再次感謝小明兄,技術可見厲害。  回復  更多評論
              
            # re: 數據結構之網格實現
            2006-01-16 22:12 | 萬連文
            問題一已經修改,添加兩個接口函數
            // 添加一個單元格,bRight=true表示添加在pos后面
            // 可能修改m_pHead、m_pTail
            // 返回<=0表示添加失敗;>0表示成功
            int AddCell(T xData, WLWGridCell<T>* pPos, bool bRight=true);

            // 添加一個單元格,iIndex是索引,bRight=true表示添加在iIndex后面
            // 可能修改m_pHead、m_pTail
            // 返回<=0表示添加失敗;>0表示成功
            int AddCell(T xData, int iIndex, bool bRight=true);
            問題二無法修改,因為不想拷貝,使用的時候必須要交付內存管理權限否則無法正確運行,必須注意。  回復  更多評論
              
            # re: 數據結構之網格實現
            2006-01-17 20:48 | 萬連文
            針對以上建議做如下修改:
            2006-1-16
            WLWGridRow類添加兩個函數接口以方便用戶使用:
            int AddCell(T xData, WLWGridCell<T>* pPos, bool bRight=true);
            int AddCell(T xData, int iIndex, bool bRight=true);

            2006-1-17
            WLWGridRow類和WLWGrid類接口傳遞指針方式改為傳遞指針引用,
            為了避免用戶傳入棧地址導致兩次析構,如:
            int AddCell(WLWGridCell<T>* pCell, int iIndex, bool bRight=true);
            改為:
            int AddCell(WLWGridCell<T>*& pCell, int iIndex, bool bRight=true);

            2006-1-17
            WLWGridRow類添加一個拷貝構造函數  回復  更多評論
              
            簡歷下載
            聯系我

            <2012年8月>
            2930311234
            567891011
            12131415161718
            19202122232425
            2627282930311
            2345678

            常用鏈接

            留言簿(66)

            隨筆分類

            隨筆檔案

            相冊

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久久久久亚洲Av无码精品专口| 狠狠人妻久久久久久综合蜜桃| 日韩美女18网站久久精品| 国产99久久久久久免费看| 久久www免费人成精品香蕉| 久久精品视屏| 欧美va久久久噜噜噜久久| 99久久超碰中文字幕伊人| 久久免费香蕉视频| 少妇高潮惨叫久久久久久| 办公室久久精品| 久久久久久亚洲精品成人| 欧美精品一区二区久久| 国产精品久久久久…| 亚洲国产视频久久| 亚洲国产精品久久久久婷婷软件| 欧美日韩精品久久久久| 国产高清国内精品福利99久久 | 亚洲狠狠婷婷综合久久蜜芽| 97久久超碰成人精品网站| 中文成人无码精品久久久不卡| 狠狠狠色丁香婷婷综合久久俺| 亚洲а∨天堂久久精品| 国产亚洲色婷婷久久99精品91 | 精品熟女少妇a∨免费久久| 蜜臀久久99精品久久久久久| 日韩精品国产自在久久现线拍| 亚洲中文精品久久久久久不卡| 久久久久亚洲AV成人网人人网站 | 99久久这里只精品国产免费| 久久综合丝袜日本网| 久久香综合精品久久伊人| 中文字幕无码av激情不卡久久| 国产三级精品久久| AAA级久久久精品无码区| 66精品综合久久久久久久| 久久av无码专区亚洲av桃花岛| 午夜精品久久久久久久| 欧美噜噜久久久XXX| 久久婷婷五月综合国产尤物app| 久久精品卫校国产小美女|