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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构基础(11) --循环链表的设计与实现

發布時間:2025/3/17 编程问答 13 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构基础(11) --循环链表的设计与实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

循環鏈表:最后一個結點的指針域的指針又指回第一個結點的鏈表;

? ? 循環單鏈表與單鏈表的區別在于:表中最有一個節點的指針不再是NULL,?而改為指向頭結點(因此要對我們原來的MyList稍作修改),?從而整個鏈表形成一個環.

? ? 因此,?循環單鏈表的判空條件不再是頭結點的指針是否為空,?而是他是否等于頭結點;

? ? 其實如果只是單純的實現循環鏈表對單鏈表的性能提升是不明顯的,?反而增加了代碼上實現的復雜度,?但是如果與下一篇中的雙向鏈表相結合的話,?在速度上的提升是十分驚人的,?因此這篇博客權當做是一個過渡吧,?為上一篇博客和下一篇博客的結合起著承上啟下的作用.

?

? ? 下面是MyList.h的完整代碼與解析,?由于代碼較多,?希望能夠仔細閱讀,?但其實下面的大部分代碼都與前面類似只是對其中幾處稍作修改,?遇到與單鏈表的不同之處,?我會與++符號作為注釋指出:

#ifndef MYLIST_H_INCLUDED #define MYLIST_H_INCLUDED#include <iostream> #include <stdexcept> using namespace std;//循環鏈表 //前向聲明 template <typename Type> class MyList; template <typename Type> class ListIterator;//鏈表節點 template <typename Type> class Node {//可以將MyList類作為Node的友元//同時也可以將Node類做成MyList的嵌套類, 嵌套在MyList中, 也可以完成該功能friend class MyList<Type>;friend class ListIterator<Type>;template <typename T>friend ostream &operator<<(ostream &os, const MyList<T> &list); private://constructor說明://next = NULL; //因為這是一個新生成的節點, 因此下一個節點為空Node(const Type &dataValue):data(dataValue), next(NULL) {}Type data; //數據域:節點數據Node *next; //指針域:下一個節點 };//鏈表 template <typename Type> class MyList {template <typename T>friend ostream &operator<<(ostream &os, const MyList<T> &list);friend class ListIterator<Type>; public:MyList();~MyList();//將元素插入表頭void insertFront(const Type &data);//將元素插入到位置index上(index從1開始)void insert(const Type &data, int index);//刪除表中所有值為data的節點void remove(const Type &data);bool isEmpty() const;private://指向第一個節點的指針Node<Type> *first; };template <typename Type> MyList<Type>::MyList() {//first指向一個空節點first = new Node<Type>(0);// ++ 這是一個關鍵點//first的下一個元素就指向first//此時, 代表鏈表是否已經到達結尾處的判斷已經不再是(是否等于NULL)//而改為(是否等于first)//因為此時first代表鏈表的最后一個元素//同時,first又是第一個元素的前一個元素first -> next = first; }template <typename Type> MyList<Type>::~MyList() {Node<Type> *deleteNode = NULL;// ++ 保存鏈表尾元素Node<Type> *tmp = first;// ++ first首先指向第一個真實的元素first = first->next;//一路到達鏈表結尾while (first != tmp){deleteNode = first;first = first -> next;delete deleteNode;}// ++ 釋放到鏈表的空節點delete tmp; }//這一步與前一版鏈表相同 template <typename Type> void MyList<Type>::insertFront(const Type &data) {Node<Type> *newNode = new Node<Type>(data);newNode -> next = first -> next;first -> next = newNode; }template <typename Type> void MyList<Type>::insert(const Type &data, int index) {//由于我們在表頭添加了一個空節點//因此如果鏈表為空, 或者在鏈表為1的位置添加元素//其操作與在其他位置添加元素相同int count = 1;//此時searchNode肯定不為firstNode<Type> *searchNode = first;//++ 注意:此處將NULL修改為first// 找到要插入的位置// 如果所給index過大(超過了鏈表的長度)// 則將該元素插入到鏈表表尾// 原因是 searchNode->next != first 這個條件已經不滿足了while (count < index && searchNode->next != first){++ count;searchNode = searchNode->next;}// 插入鏈表Node<Type> *newNode = new Node<Type>(data);newNode->next = searchNode->next;searchNode->next = newNode; }template <typename Type> void MyList<Type>::remove(const Type &data) {if (isEmpty())return ;Node<Type> *previous = first; //保存要刪除節點的前一個節點for (Node<Type> *searchNode = first->next;//searchNode != NULL; // ++ 注意此處不再是判斷是否為NULLsearchNode != first; // ++ 而是不能等于first, first代表鏈表的末尾searchNode = searchNode->next){if (searchNode->data == data){previous->next = searchNode->next;delete searchNode;//重新調整searchNode指針//繼續遍歷鏈表查看是否還有相等元素// ++ 注意//如果當前searchNode已經到達了最后一個節點//也就是searchNode->next已經等于first了, 則下面這條語句不能執行if (previous->next == first)break;searchNode = previous->next;}previous = searchNode;} } //注意判空條件 template <typename Type> bool MyList<Type>::isEmpty() const {return first->next == first; }//顯示鏈表中的所有數據(測試用) template <typename Type> ostream &operator<<(ostream &os, const MyList<Type> &list) {for (Node<Type> *searchNode = list.first -> next;searchNode != list.first; //++ 注意searchNode = searchNode -> next){os << searchNode -> data;if (searchNode -> next != list.first) // ++ 注意(尚未達到鏈表的結尾)cout << " -> ";}return os; }//ListIterator 除了判空函數的判空條件之外, 沒有任何改變 template <typename Type> class ListIterator { public:ListIterator(const MyList<Type> &_list):list(_list),currentNode((_list.first)->next) {}//重載 *operatorconst Type &operator*() const throw (std::out_of_range);Type &operator*() throw (std::out_of_range);//重載 ->operatorconst Node<Type> *operator->() const throw (std::out_of_range);Node<Type> *operator->() throw (std::out_of_range);//重載 ++operatorListIterator &operator++() throw (std::out_of_range);//注意:此處返回的是值,而不是referenceListIterator operator++(int) throw (std::out_of_range);bool isEmpty() const;private:const MyList<Type> &list;Node<Type> *currentNode; };template <typename Type> bool ListIterator<Type>::isEmpty() const {// ++ 注意:判空條件改為list.firstif (currentNode == list.first)return true;return false; } template <typename Type> const Type &ListIterator<Type>::operator*() const throw (std::out_of_range) {if (isEmpty())throw std::out_of_range("iterator is out of range");// 返回當前指針指向的內容return currentNode->data; } template <typename Type> Type &ListIterator<Type>::operator*() throw (std::out_of_range) {//首先為*this添加const屬性,//以調用該函數的const版本,//然后再使用const_case,//將該函數調用所帶有的const屬性轉除//operator->()的non-const版本與此類同returnconst_cast<Type &>(static_cast<const ListIterator<Type> &>(*this).operator*()); }template <typename Type> const Node<Type> *ListIterator<Type>::operator->() const throw (std::out_of_range) {if (isEmpty())throw std::out_of_range("iterator is out of range");//直接返回指針return currentNode; }template <typename Type> Node<Type> *ListIterator<Type>::operator->() throw (std::out_of_range) {// 見上returnconst_cast<Node<Type> *> (static_cast<const ListIterator<Type> >(*this).operator->()); }template <typename Type> ListIterator<Type> &ListIterator<Type>::operator++() throw (std::out_of_range) {if (isEmpty())throw std::out_of_range("iterator is out of range");//指針前移currentNode = currentNode->next;return *this; } template <typename Type> ListIterator<Type> ListIterator<Type>::operator++(int) throw (std::out_of_range) {ListIterator tmp(*this);++ (*this); //調用前向++版本return tmp; }#endif // MYLIST_H_INCLUDED

附-測試代碼:

int main() {MyList<int> iMyList;for (int i = 0; i < 10; ++i) //1 2 3 4 5 6 7 8 9 10iMyList.insert(i+1, i+1);for (int i = 0; i < 5; ++i) //40 30 20 10 0 1 2 3 4 5 6 7 8 9 10iMyList.insertFront(i*10);iMyList.insertFront(100);//100 40 30 20 10 0 1 2 3 4 5 6 7 8 9 10iMyList.remove(10); //100 40 30 20 0 1 2 3 4 5 6 7 8 9iMyList.remove(8); //100 40 30 20 0 1 2 3 4 5 6 7 9cout << "------------ MyList ------------" << endl;for (ListIterator<int> iter(iMyList);!(iter.isEmpty());++ iter)cout << *iter << ' ';cout << endl;cout << "Test: \n\t" << iMyList << endl;return 0; }

總結

以上是生活随笔為你收集整理的数据结构基础(11) --循环链表的设计与实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 91成人小视频 | 污污视频免费看 | 蜜桃臀aⅴ精品一区二区三区 | av亚州 | 国产天堂精品 | 老太脱裤让老头玩ⅹxxxx | 狠狠操网 | 波多野结衣欧美 | 欧美日韩在线视频免费 | 2019毛片| 伊人网在线 | 亚洲一区成人在线 | 软萌小仙自慰喷白浆 | 亚洲国产精品久久久久婷婷老年 | 国产精品99久久久久久动医院 | 黄色小说网站在线观看 | 雨宫琴音一区二区三区 | 日韩欧美极品 | 国产一区二区三区视频在线播放 | 开心激情久久 | 日韩欧美国产激情 | 96久久精品 | 96国产精品| 先锋av资源网站 | 香蕉av在线播放 | 午夜国产在线观看 | 韩国三级hd中文字幕叫床浴室 | 欧美成人看片黄a免费看 | 国产精品mm| 亚洲一区三区 | 簧片av| 天天夜夜草 | 国产在线精品一区二区三区 | 日韩一级片免费观看 | 日本少妇网站 | 亚洲精品乱码久久久久久按摩观 | 成人免费视频国产免费麻豆 | 黄瓜视频在线免费看 | 国产视频久久久久久久 | 久久人人爽人人爽人人片av免费 | 欧美日韩一区在线 | 国产在线天堂 | 中文字幕日韩欧美一区二区三区 | 色爱AV综合网国产精品 | 无码久久精品国产亚洲av影片 | 精品日韩在线观看 | 超爽视频| 亚洲国产mv | 狠狠搞狠狠干 | 国产永久在线观看 | 91日日| 天天射天天色天天干 | 美女100%视频免费观看 | 成年人视频网站 | 伊人加勒比 | 人人澡人人干 | 一区二区久久精品66国产精品 | 91综合视频| 欧美日韩一区二区三区 | 日韩少妇中文字幕 | 日本a级一区 | 一区二区在线免费看 | 国产又粗又猛又黄又爽视频 | 中文字幕在线免费看线人 | 五月深爱婷婷 | 日韩一区二区视频在线播放 | 国产乱码精品一区二区三区亚洲人 | 午夜生活片 | 国产高潮国产高潮久久久91 | 亚洲高清av在线 | 男女搞网站 | 一本之道高清无码视频 | 女~淫辱の触手3d动漫 | 情涩快播 | 一区久久久 | 精品麻豆av | 懂色视频在线观看 | 久久精品色妇熟妇丰满人妻 | 巨乳美女在线 | 欧美性猛交富婆 | 激情视频免费在线观看 | 无码人妻精品一区二区三区不卡 | 中国a级黄色片 | hd丰满圆润的女人hd | 国产裸体永久免费无遮挡 | 超碰资源在线 | 欧美日韩在线观看一区 | 久久高清精品 | 无法忍受在线观看 | 三级黄色在线 | 激情丁香婷婷 | 免费的黄色网址 | 久久公开视频 | 国产高清自拍一区 | 久久狠狠干| 久久亚洲免费 | 国产男女无套免费网站 | www.五月.com| 色图综合 |