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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

DualLinkList

發布時間:2025/4/5 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DualLinkList 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

    • 1 單鏈表的缺陷
    • 2 雙向鏈表的實現
      • 2.1 設計思路
      • 2.2 雙向鏈表的繼承層次結構
      • 2.3 DualLinkList的定義
      • 2.4 雙向鏈表的特點
    • 3 代碼實現
    • 4 開放性問題

1 單鏈表的缺陷

單鏈表具有單向性,只能從頭結點開始高效訪問鏈表中的數據元素。
缺陷: 如果需要逆向訪問單鏈表中的數據元素將極其低效。


2 雙向鏈表的實現

2.1 設計思路

在單鏈表的結點中增加一個指針pre,用于指向當前結點的前驅結點。

2.2 雙向鏈表的繼承層次結構

2.3 DualLinkList的定義

2.4 雙向鏈表的特點

  • 雙向鏈表是為了彌補單鏈表的缺陷而重新設計的。
  • 在概念上,雙向鏈表不是單鏈表,沒有繼承關系。
  • 雙向鏈表中的游標能夠直接訪問當前結點的前驅和后繼。
  • 雙向鏈表是線性表的最終實現(更貼近理論上的線性表)。

3 代碼實現

DualLinkList.h

#ifndef DUALLINKLIST_H #define DUALLINKLIST_H#include "List.h" #include "Exception.h"namespace LemonLib { template < typename T > class DualLinkList : public List<T> { protected:struct Node : public Object{T value;Node* next;Node* pre;};/* 注意:當前結構體必須繼承自Object類,否則會導致和Node的內存布局不同,直接拋出異常 */mutable struct : public Object{char reserved[sizeof(T)];Node* next;Node* pre;}m_header;int m_length;Node* m_current;int m_step;Node* position(int index) const{Node* ret = reinterpret_cast<Node*>(&m_header);for (int i=0; i<index; i++){ret = ret->next;}return ret;}virtual Node* create(){return new Node();}virtual void destroy(Node* pn){delete pn;} public:DualLinkList(){m_header.next = NULL;m_header.pre = NULL;m_length = 0;m_current = NULL;m_step = 0;}bool insert(int index, const T& e){bool ret = (0 <= index) && (index <= m_length);if (ret){Node* node = create();if (node != NULL){Node* current = position(index);Node* next = current->next;node->value = e;node->next = next; // 當前結點的next指針指向下一個結點current->next = node;if (current != reinterpret_cast<Node*>(&m_header)) // 當前插入的位置不是首結點{node->pre = current;}else{node->pre = NULL;}if (next != NULL) // 當前插入的不是最后一個結點{next->pre = node;}m_length++;}else{THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to inset element ...");}}return ret;}bool insert(const T& e)// 插入到尾部{return insert(m_length, e);}bool remove(int index){bool ret = (0 <= index) && (index < m_length);if (ret){Node* current = position(index);Node* toDel = current->next;Node* next = toDel->next;current->next = toDel->next;if (next != NULL){next->pre = toDel->pre;}if (m_current == toDel){m_current = toDel->next;}m_length--;destroy(toDel);}return ret;}bool set(int index, const T& e){bool ret = (0 <= index) && (index < m_length);if (ret){position(index)->next->value = e;}return ret;}bool get(int index, T& e) const{bool ret = (0 <= index) && (index < m_length);if (ret){e = position(index)->next->value;}return ret;}virtual T get(int index) const{T ret;if (get(index, ret)){return ret;}else{THROW_EXCEPTION(InvalidParameterException, "Invalid parameter in get element...");}}int find(const T& e) const{int ret = -1;int index = 0;Node* current = m_header.next;while (current){if (current->value == e){ret = index;break;}else{index++;current = current->next;}}return ret;}virtual bool move(int index, int step = 1){bool ret = ((0 <= index) && (index < m_length) && (step > 0));if (ret){m_current = position(index)->next;m_step = step;}return ret;}virtual bool end(){return (m_current == NULL);}virtual T current(){if (!end()){return m_current->value;}else{THROW_EXCEPTION(InvalidOperationException, "Invalid operation to get current value ...");}}virtual bool next(){int i = 0;while ((i < m_step) && (!end())){m_current = m_current->next;i++;}return (i == m_step);}virtual bool pre(){int i = 0;while ((i < m_step) && (!end())){m_current = m_current->pre;i++;}return (i == m_step);}int length() const{return m_length;}void clear(){while (m_length > 0){remove(0);}}~DualLinkList(){clear();} }; }#endif // DUALLINKLIST_H

main.cpp

#include <iostream>#include "SmartPointer.h" #include "Exception.h" #include "Object.h" #include "List.h" #include "SeqList.h" #include "StaticList.h" #include "DynamicList.h" #include "Array.h" #include "StaticArray.h" #include "DynamicArray.h" #include "LinkList.h" #include "StaticLinkList.h" #include "Pointer.h" #include "SmartPointer.h" #include "SharedPointer.h" #include "CircleList.h" #include "DualLinkList.h"using namespace std; using namespace LemonLib;int main() {DualLinkList<int> dl;for (int i=0; i<5; i++){dl.insert(0, i);dl.insert(0, 8);}int ret = -1;while ((ret = dl.find(8)) != -1){dl.remove(ret);}#if 0 // 這樣刪除的意義不大dl.move(dl.length()-1);while (!dl.end()){if (dl.current() == 8){dl.remove(dl.find(8));}else{dl.pre();}} #endif#if 1for (dl.move(0); !dl.end(); dl.next()){cout << dl.current() << endl;} #endif#if 0for (dl.move(dl.length()-1); !dl.end(); dl.pre()){cout << dl.current() << endl;} #endif#if 0for (int i=0; i<5; i++){cout << dl.get(i) << endl;} #endifreturn 0; }

4 開放性問題

DualLinkList和LinkList中存在很多完全一樣的代碼,如何進行重構降低代碼的冗余性?冗余代碼的出現是否意味著DualLinkList和LinkList之間應該是繼承關系?

解決這個問題的方法就是DualLinkList繼承LinkList,從而降低代碼的冗余性。關于DualLinkList是否設計為LinkList的子類,這只是設計理念不同而已。

總結

以上是生活随笔為你收集整理的DualLinkList的全部內容,希望文章能夠幫你解決所遇到的問題。

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