slist是sgi stl裡面的乙個單向鍊錶,不過這個不屬於標準定義,所以,g++下面不能用,另外看了下vs2008裡面也沒有。不過看到書上這一部分講解,還是配合sgi的**做乙個了解。一般情況下使用標準的list就可以滿足要求了,而且會更加方便,list的分析可以參考stl筆記之list一文。因為slist是單向鍊錶,所以它的迭代器型別為forward_iterator。
1. slist節點設計
鍊錶最基本的結構就是指標域和資料域,對單向鍊錶的節點而言,其擁有乙個next指標,指向下乙個節點,同時擁有乙個資料域用於儲存節點的資料。slist在這裡做了乙個分層處理,基類_slist_node_base只有next指標,用於鍊錶的構造,子類_slist_node繼承自_slist_node_base,同時擁有乙個儲存資料的成員。
// node 基類
struct _slist_node_base;
// slist_node
template struct _slist_node : public _slist_node_base
;
一些基本的函式操作,基於_slist_node_base指標型別。可以看到因為單鏈表只能往後迭代,所以很多操作都沒有提供,即使提供了,也是非常低效的操作,需要從頭結點開始遍歷。
// 在prev後面插入新節點,返回指向新的節點的指標
inline _slist_node_base*
__slist_make_link(_slist_node_base* __prev_node,
_slist_node_base* __new_node)
// 返回指定節點的上乙個節點,需要從head開始遍歷
inline _slist_node_base*
__slist_previous(_slist_node_base* __head,
const _slist_node_base* __node)
// 拼接操作:將[before_first->next, before_last]拼接到pos後
inline void __slist_splice_after(_slist_node_base* __pos,
_slist_node_base* __before_first,
_slist_node_base* __before_last)}
// 將head指向的鍊錶拼接到pos之後
inline void
__slist_splice_after(_slist_node_base* __pos, _slist_node_base* __head)}
// 翻轉鍊錶
inline _slist_node_base* __slist_reverse(_slist_node_base* __node)
return __result;}
// 求鍊錶的節點個數
inline size_t __slist_size(_slist_node_base* __node)
2. slist迭代器設計
slist的迭代器屬於forward iterator,只能往前迭代,因此除了迭代器的基本操作之外,只實現了operator++操作。
// iterator基類
struct _slist_iterator_base
// 只提供往前訪問的方法
void _m_incr()
bool operator==(const _slist_iterator_base& __x) const
bool operator!=(const _slist_iterator_base& __x) const };
// 迭代器定義
template struct _slist_iterator : public _slist_iterator_base
_slist_iterator() : _slist_iterator_base(0) {}
_slist_iterator(const iterator& __x) : _slist_iterator_base(__x._m_node) {}
reference operator*() const
pointer operator->() const
_self& operator++()
_self operator++(int)
};
3. slist設計
slist也是分層的設計,_slist_base中定義了乙個型別為_slist_node_base的_m_head成員,head.next即指向鍊錶的第乙個節點。
template struct _slist_base
// 建構函式,將head.next置為空
_slist_base(const allocator_type&)
// 析構函式, 通過呼叫_m_erase_after刪除所有節點
~_slist_base()
protected:
typedef ******_alloc<_slist_node<_tp>, _alloc> _alloc_type;
_slist_node<_tp>* _m_get_node()
void _m_put_node(_slist_node<_tp>* __p)
// 刪除指定節點後面的節點
_slist_node_base* _m_erase_after(_slist_node_base* __pos)
_slist_node_base* _m_erase_after(_slist_node_base*, _slist_node_base*);
protected:
_slist_node_base _m_head;
};
// 刪除指定節點之後的節點:區間[before_first->next, last)
template _slist_node_base*
_slist_base<_tp,_alloc>::_m_erase_after(_slist_node_base* __before_first,
_slist_node_base* __last_node)
__before_first->_m_next = __last_node;
return __last_node;
}
slist基本結構定義:
template class slist : private _slist_base<_tp,_alloc>
private:
typedef _slist_node<_tp> _node;
typedef _slist_node_base _node_base;
typedef _slist_iterator_base _iterator_base;
_node* _m_create_node(const value_type& __x)
__stl_unwind(this->_m_put_node(__node));
return __node;
} _node* _m_create_node()
__stl_unwind(this->_m_put_node(__node));
return __node;
} public:
iterator begin()
iterator end()
size_type size() const
size_type max_size() const
bool empty() const
void swap(slist& __x)
public:
reference front()
void push_front(const value_type& __x)
void pop_front()
iterator previous(const_iterator __pos)
private:
_node* _m_insert_after(_node_base* __pos, const value_type& __x)
public:
void reverse()
};
4. slist排序
slist的sort**與list的sort**非常類似,可以參考list sort一節。
template void slist<_tp,_alloc>::sort()
__carry.swap(__counter[__i]);
if (__i == __fill)
++__fill;
}for (int __i = 1; __i < __fill; ++__i)
__counter[__i].merge(__counter[__i-1]);
this->swap(__counter[__fill-1]);
}}
至此,stl常見序列容器基本分析完畢,接下來準備看看關聯容器,以及記錄一下使用stl過程中遇到的一些「坑」(比如最近使用sort導致了core dump)。
stl之順序容器學習筆記1
初窺容器 容納特定型別物件的集合,稱為容器。將單一型別的元素聚集起來成為容器,然後根據位置來儲存和訪問元素,稱為順序容器。順序容器的排列次序,按照元素新增到容器的次序決定。stl定義了三種順序容器 1 vector 2 list 3 deque 他們的差異在於訪問元素的方式,以及做新增 刪除元素時的...
stl之順序容器學習筆記3
vector容器的自增長 概述vector物件為了支援快速隨機的訪問,將元素以連續的方式存放 與陣列相同 當我們向vector中新增乙個元素時,如果容器已經沒有空間容納新的元素,此時,由於元素必須連續存放以實現快速索引,所以不能在記憶體中隨便找個地方來儲存這個元素。於是,vector必須重新分配儲存...
stl之關聯容器學習筆記1
概述 stl定義了另一種容器,名曰關聯容器,關聯容器和順序容器的本質區別在於 關聯容器通過鍵key來儲存和讀取元素,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。關聯容器的大部分行為與順序容器相同,但其獨特之處在於支援鍵的使用。stl提供了兩個基本的關聯容器 1 map 容器中以鍵值的形式來...