日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ :跳表数据结构的实现原理

發布時間:2024/10/14 c/c++ 79 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ :跳表数据结构的实现原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 所謂的跳表,就是在有序鏈表的基礎上加上索引層,在索引層的基礎上還可以再加索引層,從而提高鏈表的查詢效率,一般情況下也可以提高插入和刪除效率。

-----------------------------------------------------------------------

目錄

一、跳表的數據結構

二、重建索引

三、根據位置確定數據節點

四、根據元素data信息來查詢元素位置

五、插入和刪除


一、跳表的數據結構

? ? ? 跳表由索引層鏈表和數據層鏈表組成,數據層鏈表由 next指針部分和數據部分組成。索引層鏈表由 數據部分、索引指針部分、next指針部分三部分組成,其中數據部分值和索引指針指向節點的值保持一致。最底層的索引指針指向數據層鏈表節點,其它層索引指針指向低層的索引鏈表節點。

template<class ElemType>class SkipList {public:class IndexStruct{public:ElemType position() const;void position(ElemType position);bool operator <(IndexStruct a);bool operator ==(IndexStruct a);bool operator >(IndexStruct a);IndexStruct& operator =(const IndexStruct & a);IndexStruct(ElemType position, const boost::shared_ptr<LinkList<ElemType>> &pointer);IndexStruct(){}public: struct U{boost::shared_ptr<LinkList<IndexStruct>> indexPointer;boost::shared_ptr<LinkList<ElemType>> dataPointer;}pointer_;const U &pointer() const;void pointer(const U &pointer);ElemType position_; //datalist的索引位};explicit SkipList(Integer skipstep = 2):skipstep_(skipstep+1){}public:int findIndexListPosition(int indexlevel,ElemType dataPos,boost::shared_ptr<LinkList<IndexStruct>>& idxlist);void rebuildIndex(ElemType startElem );int findPosByElem(ElemType elem);void removeByPos(Size pos);boost::shared_ptr<LinkList<ElemType>> findNodeByPos(Size pos);void removeByElem(ElemType e);void insertElem(ElemType e,bool isRebuildIndex = false);boost::shared_ptr<LinkList<ElemType>>findDataNode(ElemType elem,bool isAccurate = true);boost::shared_ptr<LinkList<IndexStruct>> findIndexNode(int indexlevel,ElemType dataPos);const std::vector<boost::shared_ptr<LinkList<IndexStruct>>> &indexLinklist() const{return indexLinklist_;};void indexLinklist(const std::vector<boost::shared_ptr<LinkList<IndexStruct>>> &indexLinklist){indexLinklist_=indexLinklist;};const boost::shared_ptr<LinkList<ElemType>> &dataLinklist() const{return dataLinklist_;};void dataLinklist(const boost::shared_ptr<LinkList<ElemType>> &dataLinklist){dataLinklist_=dataLinklist;if (dataLinklist_ ->next){rebuildIndex(dataLinklist_->next->data);}else{indexLinklist_.clear();}};private:std::vector< boost::shared_ptr<LinkList<IndexStruct>>> indexLinklist_;//索引鏈表,數據是地址boost::shared_ptr<LinkList<ElemType>> dataLinklist_; //有序數據鏈表LinkListUtil<ElemType> dataListUtil_;LinkListUtil<IndexStruct> indexListUtil_;const Integer skipstep_;};

二、重建索引

? ? ? ?已知有數據層鏈表dataLinkList ,長度為 n,那么第 level層需要建立的索引數是? datalistsize /pow(skipstep_,level ) 個,每隔skipstep個數據節點就建立一個索引,直到第level層需要建立的節點數是0就不再鍵索引。在此過程中,如果層級要大于原有索引層級需要擴充索引層,否則再原來索引層進行修改。

/*** <p>從第數據鏈表的startElem開始重建立鏈表* @tparam ElemType* @param startElem*/ template<class ElemType> void SmartDongLib::SkipList<ElemType>::rebuildIndex(ElemType startElem) {//獲取數據總數int datalistsize = dataListUtil_.listLenth(dataLinklist_);//要重建數據索引的個數 // int rebuldDataCount = datalistsize - startIndex +1;//索引層應建立索引的節點數int indexlevelCount = datalistsize / skipstep_;int indexlevel=0;while (indexlevelCount !=0){//如果層級要大于 indexLinklist_.size(),需要擴充indexList,否則再原來的基礎上修改,還需要判斷是不是第0索引層if(indexlevel >= indexLinklist_.size()){boost::shared_ptr<LinkList<IndexStruct>> currentIndexList (new LinkList<IndexStruct>());//頭指針也進行關聯if (indexlevel ==0){currentIndexList->data.pointer_.dataPointer = dataLinklist_; // currentIndexList->data.position_ =dataLinklist_->data;}else{currentIndexList->data.pointer_.indexPointer = indexLinklist_[indexlevel-1]; // currentIndexList->data.position_ =indexLinklist_[indexlevel-1]->data.position_;}bool isfirst = true;boost::shared_ptr<LinkList<ElemType>> linkdataNode;boost::shared_ptr<LinkList<IndexStruct>> linkindexNode;//擴展 indexlevel 層的后面的索引for (int i = 1; i <=indexlevelCount; ++i) { // boost::shared_ptr<LinkList<IndexStruct>> currentIndexNode (new LinkList<IndexStruct>);IndexStruct currentIndexNode;//第0索引層指向data數據,其他指向下層索引數據。優化:第一次從頭節點確定指向的位置,之后再此基礎上在+上skipstep_if (indexlevel == 0) {if (isfirst){linkdataNode = dataListUtil_.listGetNode(dataLinklist_,i * skipstep_);isfirst= false;}else{linkdataNode = dataListUtil_.listGetNode(linkdataNode, skipstep_);}currentIndexNode.position_ =linkdataNode->data;currentIndexNode.pointer_.dataPointer = linkdataNode;}else{if (isfirst){linkindexNode =indexListUtil_.listGetNode(indexLinklist_[indexlevel - 1], i * skipstep_);isfirst= false;}else{linkindexNode =indexListUtil_.listGetNode(linkindexNode, skipstep_);}currentIndexNode.position_ =linkindexNode->data.position_;currentIndexNode.pointer_.indexPointer = linkindexNode;}indexListUtil_.listOrderInsert(currentIndexList,currentIndexNode);}indexLinklist_.push_back(currentIndexList);} else{//如果在原來的索引層上進行修改,那么確認要修改的索引節點進行重建boost::shared_ptr<LinkList<IndexStruct>> currentIndexList=indexLinklist_[indexlevel];//找到startElem前一個元素的位置boost::shared_ptr<LinkList<IndexStruct>> startIndexNode;int startIdx = findIndexListPosition(indexlevel, startElem,startIndexNode);//重鍵startIndexNode之后的索引startIndexNode->next = NULL;boost::shared_ptr<LinkList<ElemType>> linkdataNode;boost::shared_ptr<LinkList<IndexStruct>> linkindexNode;bool isfirst = true;//第indexlevel層從startIdx開始重建索引for (int i = startIdx+1; i <=indexlevelCount; ++i){ // boost::shared_ptr<LinkList<IndexStruct>> currentIndexNode (new LinkList<IndexStruct>); // LinkList<IndexStruct> currentIndexNode;IndexStruct currentIndexNode;//優化:第0索引層指向data數據,其他指向下層索引數據,第一次從頭節點確定指向的位置,之后再此基礎上在+上skipstep_if (indexlevel == 0) {if (isfirst){linkdataNode = dataListUtil_.listGetNode(dataLinklist_,i * skipstep_);isfirst= false;}else{linkdataNode = dataListUtil_.listGetNode(linkdataNode, skipstep_);}currentIndexNode.position_ =linkdataNode->data;currentIndexNode.pointer_.dataPointer = linkdataNode;}else{if (isfirst){linkindexNode =indexListUtil_.listGetNode(indexLinklist_[indexlevel - 1], i * skipstep_);isfirst= false;}else{linkindexNode =indexListUtil_.listGetNode(linkindexNode, skipstep_);}currentIndexNode.position_ =linkindexNode->data.position_;currentIndexNode.pointer_.indexPointer = linkindexNode;}indexListUtil_.listOrderInsert(currentIndexList,currentIndexNode);}}indexlevel++;indexlevelCount /= skipstep_;}}

三、根據位置確定數據節點

在level層移動一次next 對應的數據層節點數增加pow(skipstep_,currentIndexlevel)位置。

/*** <p>獲取節點(已優化)* @tparam ElemType* @param pos data的位置* @return 獲取pos對應的元素節點*/ template<class ElemType> boost::shared_ptr<SmartDongLib::LinkList<ElemType>> SmartDongLib::SkipList<ElemType>::findNodeByPos(Size pos) {int indexlistsize = indexLinklist_.size();int currentIndexlevel = indexlistsize-1;boost::shared_ptr<LinkList<IndexStruct>> currentIndexNode = indexLinklist_[currentIndexlevel];int currentPos = 0;int posIncrement =1;boost::shared_ptr<LinkList<ElemType>> ret = dataLinklist_;while(currentPos <= pos && currentIndexlevel >=0){posIncrement = std::pow(skipstep_,currentIndexlevel + 1);if ( currentIndexNode->next!=NULL && currentPos + posIncrement <=pos ){//如果查在后面currentIndexNode=currentIndexNode->next;currentPos +=posIncrement;}else{//如果當前層確定了位置,就下一層直到第indexlevel結束if ( currentIndexlevel == 0 ){ret = currentIndexNode->data.pointer_.dataPointer;currentIndexlevel --;break;}else{currentIndexNode = currentIndexNode->data.pointer_.indexPointer;currentIndexlevel --;}}}while (pos - currentPos >0 && currentIndexlevel<0){ret = ret->next;currentPos ++ ;}return ret; }

四、根據元素data信息來查詢元素位置

/*** <p>根據元素尋找在datalinklist中的位置(已優化)* @tparam ElemType* @param elem* @return 位找到是-1 ,頭節點是第0個位置*/ template<class ElemType> int SmartDongLib::SkipList<ElemType>::findPosByElem(ElemType elem) {int indexlistsize = indexLinklist_.size();int currentIndexlevel = indexlistsize-1;boost::shared_ptr<LinkList<IndexStruct>> idxlist=indexLinklist_[currentIndexlevel];int pos = 0;while (currentIndexlevel >= 0){if ( idxlist->next && idxlist->next->data.position() <= elem ){//如果查在后面idxlist=idxlist->next;pos =pos + std::pow(skipstep_,currentIndexlevel +1 );}else{//如果當前層確定了位置,就下一層直到第indexlevel結束if ( currentIndexlevel == 0 ){break;}else{idxlist = idxlist->data.pointer_.indexPointer;currentIndexlevel --;}}}boost::shared_ptr<LinkList<ElemType>> dataNode = idxlist->data.pointer_.dataPointer;if (dataNode ->data == elem){return pos;} else{int rslt =dataListUtil_.listGetIndex(dataNode,elem);if (rslt == -1 )return -1;elsereturn pos + dataListUtil_.listGetIndex(dataNode,elem);} }

五、插入和刪除

? ? ? ?查詢到要插入的節點位置后,進行普通有序鏈表的插入和刪除即可

總結

以上是生活随笔為你收集整理的C++ :跳表数据结构的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。