本篇內(nèi)容介紹了“如何用Linux內(nèi)核鏈表來實(shí)現(xiàn)DTLib中的雙向循環(huán)鏈表”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
創(chuàng)新互聯(lián)建站專注于蓬萊網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠(chéng)為您提供蓬萊營(yíng)銷型網(wǎng)站建設(shè),蓬萊網(wǎng)站制作、蓬萊網(wǎng)頁(yè)設(shè)計(jì)、蓬萊網(wǎng)站官網(wǎng)定制、小程序開發(fā)服務(wù),打造蓬萊網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供蓬萊網(wǎng)站排名全網(wǎng)營(yíng)銷落地服務(wù)。繼承關(guān)系如下圖所示
下來我們來講講它的設(shè)計(jì)思路:數(shù)據(jù)結(jié)點(diǎn)之間在邏輯上構(gòu)成雙向循環(huán)鏈表,頭結(jié)點(diǎn)僅用于結(jié)點(diǎn)的定位。如下圖所示
實(shí)現(xiàn)思路:
1、通過模板定義 DualCircleList 類。繼承自 DualLinkList 類;
2、在 DualCircleList 內(nèi)部使用 Linux 內(nèi)核鏈表進(jìn)行實(shí)現(xiàn);
3、使用 struct list_head 定義 DualCircleList 的頭結(jié)點(diǎn);
4、特殊處理:循環(huán)遍歷時(shí)忽略頭結(jié)點(diǎn)
實(shí)現(xiàn)要點(diǎn):
1、通過 list_head 進(jìn)行目標(biāo)結(jié)點(diǎn)定位(position(i));
2、通過 list_entry 將 list_head 指針轉(zhuǎn)換為目標(biāo)結(jié)點(diǎn)指針;
3、通過 list_for_each 實(shí)現(xiàn) int find(const T& e) 函數(shù);
4、遍歷函數(shù)中的 next() 和 pre() 需要考慮跳過頭結(jié)點(diǎn)
下來我們來看看基于 Linux 內(nèi)核鏈表的雙向循環(huán)鏈表是怎樣寫的
DualCircleList 源碼
#ifndef DUALCIRCLELIST_H #define DUALCIRCLELIST_H #include "DualLinkList.h" #include "LinuxList.h" namespace DTLib { template < typename T > class DualCircleList : public DualLinkList<T> { protected: struct Node : public Object { list_head head; T value; }; list_head m_header; list_head* m_current; list_head* position(int i) const { list_head* ret = const_cast<list_head*>(&m_header); for(int p=0; p<i; p++) { ret = ret->next; } return ret; } int mod(int i) const { return (this->m_length == 0) ? 0 : (i % this->m_length); } public: DualCircleList() { this->m_length = 0; this->m_step = 1; m_current = NULL; INIT_LIST_HEAD(&m_header); } bool insert(const T& e) { return insert(this->m_length, e); } bool insert(int i, const T& e) { bool ret = true; Node* node = new Node(); i = i % (this->m_length + 1); if(node != NULL) { node->value = e; list_add_tail(&node->head, position(i)->next); this->m_length++; } else { THROW_EXCEPTION(NoEnoughMemoryException, "No memory to insert new element ..."); } return ret; } bool remove(int i) { bool ret = true; i = mod(i); ret = ((0 <= i) && (i < this->m_length)); if( ret ) { list_head* toDel = position(i)->next; if( m_current == toDel ) { m_current = toDel->next; } list_del(toDel); this->m_length--; delete list_entry(toDel, Node, head); } return ret; } bool set(int i, const T& e) { bool ret = true; i = mod(i); ret = ((0 <= i) && (i < this->m_length)); if( ret ) { list_entry(position(i)->next, Node, head)->value = e; } return ret; } T get(int i) const { T ret; if( get(i, ret) ) { return ret; } else { THROW_EXCEPTION(IndexOutOfBoundsException, "Invaild parameter i to get element ..."); } } bool get(int i, T& e) const { bool ret = true; i = mod(i); ret = ((0 <= i) && (i < this->m_length)); if( ret ) { e = list_entry(position(i)->next, Node, head)->value; } return ret; } int find(const T& e) const { int ret = -1; int i = 0; list_head* slider = NULL; list_for_each(slider, &m_header) { if( list_entry(slider, Node, head)->value == e ) { ret = i; break; } i++; } return ret; } int length() const { return this->m_length; } void clear() { while( this->m_length > 0 ) { remove(0); } } bool move(int i, int step = 1) { bool ret = (step > 0); i = mod(i); ret = ret && ((0 <= i) && (i < this->m_length)); if( ret ) { m_current = position(i)->next; this->m_step = step; } return ret; } bool end() { return (m_current == NULL) || (this->m_length == 0); } T current() { if( !end() ) { return list_entry(m_current, Node, head)->value; } else { THROW_EXCEPTION(INvalidOPerationException, "No value at current position ..."); } } bool next() { int i = 0; while( (i < this->m_step) && !end() ) { if( m_current != &m_header ) { m_current = m_current->next; i++; } else { m_current = m_current->next; } } if( m_current == &m_header ) { m_current = m_current->next; } return (i == this->m_step); } bool pre() { int i =0; while( (i < this->m_step) && !end() ) { if( m_current != &m_header ) { m_current = m_current->next; i++; } else { m_current = m_current->prev; } } if( m_current == &m_header ) { m_current = m_current->next; } return (i == this->m_step); } ~DualCircleList() { clear(); } }; } #endif // DUALCIRCLELIST_H
下來我們寫點(diǎn)測(cè)試代碼看看上面的代碼有沒有問題
main.cpp 源碼
#include <iostream> #include "DualCircleList.h" using namespace std; using namespace DTLib; int main() { DualCircleList<int> d1; for(int i=0; i<5; i++) { d1.insert(0, i); d1.insert(0, 5); } cout << "begin" << endl; d1.move(d1.length()-1); while( d1.find(5) != -1 ) { if( d1.current() == 5 ) { cout << d1.current() << endl; d1.remove(d1.find(d1.current())); } else { d1.pre(); } } cout << "end" << endl; for(int i=0; i<d1.length(); i++) { cout << d1.get(i) << endl; } return 0; }
我們先來分析下,在插入 i 后,隨后便插入 5。先打印出 5 個(gè) 5,隨后刪除這 5 個(gè)數(shù),然后在打印出剩下的 4 ~ 0??纯唇Y(jié)果是否如我們所分析的那樣
“如何用Linux內(nèi)核鏈表來實(shí)現(xiàn)DTLib中的雙向循環(huán)鏈表”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
分享名稱:如何用Linux內(nèi)核鏈表來實(shí)現(xiàn)DTLib中的雙向循環(huán)鏈表-創(chuàng)新互聯(lián)
當(dāng)前地址:http://www.rwnh.cn/article6/dsdcig.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、外貿(mào)建站、網(wǎng)站導(dǎo)航、域名注冊(cè)、網(wǎng)站維護(hù)、全網(wǎng)營(yíng)銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
移動(dòng)網(wǎng)站建設(shè)知識(shí)