CircleList
生活随笔
收集整理的這篇文章主要介紹了
CircleList
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1 循環鏈表的實現
- 1.1 什么是循環鏈表
- 1.2 循環鏈表的邏輯構成
- 1.3 循環鏈表的繼承層次結構
- 1.4 循環鏈表的實現思路
- 1.5 循環鏈表的實現要點
- 2 代碼實現
- 3 循環鏈表的應用
1 循環鏈表的實現
1.1 什么是循環鏈表
概念上:
- 任意數據元素都有一個前驅和一個后繼。
- 所有的數據元素的關系構成一個邏輯上的環。
實現上:
- 循環鏈表是一種特殊的單鏈表。
- 尾結點的指針保存了首結點的地址。
1.2 循環鏈表的邏輯構成
1.3 循環鏈表的繼承層次結構
1.4 循環鏈表的實現思路
- 通過模板定義CircleList類,繼承自LinkList類。
- 定義內部函數last_to_first(),用于將單鏈表首尾相連。
- 特殊處理:首元素的插入操作和刪除操作。
- 重新實現:清空操作和遍歷操作。
1.5 循環鏈表的實現要點
插入位置為0時:
- 頭結點和尾結點均指向新結點。
- 新結點成為首結點插入鏈表。
刪除位置為0時:
- 頭節點和尾結點指向位置為1的結點。
- 安全銷毀首結點。
2 代碼實現
CircleList.h
#ifndef CIRCLELIST_H #define CIRCLELIST_H#include "LinkList.h"namespace LemonLib {template < typename T > class CircleList : public LinkList<T> { protected:typedef typename LinkList<T>::Node Node;Node* last() const{return this->position(this->m_length - 1)->next;}void last_to_first() const{last()->next = this->m_header.next;}int mod(int index) const{return (this->m_length == 0) ? 0 : (index % this->m_length);}public:bool insert(int index, const T& e){bool ret = true;index = index % (this->m_length + 1); // 由于是循環列表,所以i的值可以比較大ret = LinkList<T>::insert(index, e); // 調用父類的插入函數if (ret && (index == 0)) // 插入成功,并且插入的是第0個位置{last_to_first(); // 首尾相連}return ret;}bool insert(const T& e){return insert(this->m_length, e);}bool remove(int index){bool ret = true;index = mod(index);if (index == 0) // 刪除的為第0個元素{Node* toDel = this->m_header.next;if (toDel != NULL) // 刪除的結點有效{this->m_header.next = toDel->next;this->m_length--;if (this->m_length > 0) // 當前的結點個數大于1{last_to_first();if (this->m_current == toDel){this->m_current = toDel->next;}}else // 當前僅有一個結點{this->m_header.next = NULL;this->m_current = NULL;}this->destroy(toDel);}else // 刪除的結點無效{ret = false;}}else{ret = LinkList<T>::remove(index);}return ret;}bool get(int index, T& e) const{return LinkList<T>::get(mod(index), e);}T get(int index) const{return LinkList<T>::get(mod(index));}bool set(int index, const T& e){return LinkList<T>::insert(mod(index), e);}int find(const T& e){int ret = -1;/* 不能以如下的方式實現find函數,如果我們先把循環鏈表編程單鏈表,然后調用* 父類的find函數,如果在父類的find函數進行比較時(會重載比較操作符)拋出* 出了異常,那么我們就無法保證異常安全性,也就是拋出異常后我們的循環鏈表* 無法從單鏈表恢復為循環鏈表,也就是破壞了對象的狀態,不是異常安全的。* last()->next = NULL;* ret = this->find(e);* last_to_first();*/Node* slider = this->m_header.next;for (int i=0; i<this->m_length; i++){if (slider->value == e){ret = i;break;}slider = slider->next;}return ret;}bool move(int index, int step){return LinkList<T>::move(mod(index), step);}bool end(){return (this->m_length == 0) || (this->m_current == NULL);}void clear(){while (this->m_length > 1){remove(1); // 為了提高效率}if (this->m_length == 1){Node* toDel = this->m_header.next;this->m_header.next = NULL;this->m_current = NULL;this->m_length = 0;this->destroy(toDel);}}~CircleList(){clear();} }; }#endif // CIRCLELIST_H3 循環鏈表的應用
約瑟夫環問題:
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"using namespace std; using namespace LemonLib;void joseph(int num, int start, int step) {CircleList<int> cl;for (int i=1; i<=num; i++){cl.insert(i);}cl.move(start-1, step-1);while (cl.length() > 0){cl.next();cout << cl.current() << endl;cl.remove(cl.find(cl.current()));} }int main() {joseph(41, 1, 3);return 0; }總結
以上是生活随笔為你收集整理的CircleList的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行支行和分行区别 注意它的管辖范围
- 下一篇: ARP输入处理