要模擬實現乙個list容器,主要就是相關頭插頭刪尾插尾刪的介面,這些非常常用。
另外有乙個點灰常重要!!那就是list的迭代器,list的迭代器不能用原生指標去模擬實現,因為鍊錶的迭代器加一是下乙個節點的指標,在記憶體中兩個節點存放的位置並不連續。
因為list的迭代器會指向下乙個節點,所以我們建立乙個迭代器類,這個類成員函式就是乙個乙個節點的指標_node。該建構函式會通過乙個傳遞過來的節點來構造物件。
node* _node;
//節點的指標
//用傳過來的節點的指標構造乙個listiterator的物件
listiterator
(node* node)
:_node
(node)
鍊錶的begin和end介面都是在list類裡實現的,因為只有煉表裡才有節點的指標。
需要注意幾點:
begin是第乙個位置的迭代器,有節點的指標就能構造迭代器。
begin和end都是鍊錶實現的,迭代器是我傳過去乙個節點,他構造乙個listiterator的物件。
迭代器不是節點的指標,它是乙個listiterator的自定義型別。
listiterator可以用節點的指標構造乙個物件。
iterator begin()
iterator end()
const迭代器
我們都知道迭代器不僅有普通迭代器還有const迭代器,那麼const迭代器又該怎麼寫呢?很多人可能會想在實現乙個類,專門是const迭代器的,那這樣的話就會有大量的**冗餘了。所以怎麼辦呢?我們採用模板。
博主畫了一張呼叫邏輯~|ू・ω・` )
他們會根據模板引數的不同自動推演ref和ptr的型別。這樣的話const的就會去呼叫const的迭代器了。實現了**的復用,簡潔明瞭,是不是炒雞棒(๑•̀ㅂ•́)و✧
//節點
template
struct listnode};
//迭代器
template
struct listiterator
//實現運算子的過載,比如++,節點的指標++之後就指向連續空間的下乙個了,就找不到下乙個節點的指標了
//因此需要運算子的過載
//如節點的指標++就讓他指向下乙個節點,並且返回這個迭代器
ref operator*()
//返回的是節點裡資料的引用:為了保證可讀可寫,返回引用的話我也可以改變這個節點的值
ptr operator->()
//返回data的指標,data的指標裡才會有資料
//++it; -->it.operator++()
self& operator++()
//前置++返回++之後的
//it++;
self operator++
(int
)//後置++返回++之前的,出了作用域不在了,所以不能返回引用
self& operator--()
self operator--
(int
)//兩個迭代器進行比較的時候比較的是節點的指標,兩個指標指向的是同乙個位置說明迭代器相等
bool operator!=
(const self& s)
bool operator==
(const self& s)
//~listiterator()
//不需要寫,因為節點的生命週期是跟著鍊錶走的,鍊錶銷毀了節點才會銷毀
//迭代器不是管理乙個節點,它是封裝這個節點之後讓我們用同樣的方式去遍歷這個鍊錶,而不暴露裡面的東西
//我們可以理解為迭代器就像是乙個隔離層,遮蔽了裡面實現的東西,但是外面的使用都是一樣的};
//鍊錶
template
class list
//begin是第乙個位置的迭代器,有節點的指標就能構造迭代器,只有鍊錶才有節點的指標
//begin和end都是鍊錶實現的,迭代器是我傳過去乙個節點,他構造乙個listiterator的物件
iterator begin()
iterator end()
const_iterator begin()
const
const_iterator end()
const
list
(const list
& l)
//拷貝構造(拷貝構造要支援深拷貝,否則析構的時候會有問題)
}//現**法
list<
int>
& operator=
(list<
int> l)
~list()
void
clear()
//鍊錶的清理
//不刪除頭節點,最後要把頭節點鏈結好
_head->_next = _head;
_head->_prev = _head;
}void
pushback
(const t& x)
void
popback()
void
pushfront
(const t& x)
void
popfront()
void
insert
(iterator pos,
const t& x)
iterator erase
(iterator pos)
size_t size()
return size;
} bool empty()
private:
node* _head;
};這部分主要就是對我們模擬實現的list的測試遼!
#include
"simulate_list.h"
void
test_list1()
cout << endl;
for(
auto
& e : l)
cout << endl;
}void
printlist
(const list<
int>
& list)
cout << endl;
}void
test_list2()
void
test_list3()
void
test_list4()
void
test_list5()
else
}printlist
(l);
}int
main()
list迭代器的模擬實現
namespace bite listnode ppre listnode pnext t val list 的迭代器 迭代器有兩種實現方式,具體應根據容器底層資料結構實現 1.原生態指標,比如 vector 2.將原生態指標進行封裝,因迭代器使用形式與指標完全相同,因此在自定義的類中必須實現以下方...
C 模擬實現List
雙向鍊錶 include includeusing namespace std typedef nodenode templatestruct node t data 鍊錶中的資料 node pnext 下乙個節點 node ppre 前乙個節點 templateclass list templat...
模擬實現STL中list容器
mylist.h pragma once include reverseiterator.h templatestruct listnode 鍊錶的節點 假如沒有迭代器,而你又沒有提供print函式 即使提供也不一定能滿足使用者的列印需求 如果使用者想列印鍊錶裡面的資料,就必須知道鍊錶的內部結構 即...