10單向連結串列(slist)
1、slist概述
slist並不在標準規格之內,sllist和list的主要差別在於,slist的迭代器屬於單向的Forward Iterator,而list的迭代器屬於雙向的Bidirectional Iterator。由於slist沒有任何方便的辦法可以回頭定出前一個位置,必須從頭找起,所以對於slist除了起點外其他位置採用insert和erase操作都屬於不智之舉,這是slist相較於list的大缺點。為此,slist特別提供了insert_after()和erase_after()供靈活運用。同樣slist不提供push_back()只提供push_front(),因此slist的元素次序會和元素插入進來的次序相反。
2、slist的節點
slist節點和其迭代器的設計,架構上比list複雜許多,運用了繼承關係,因此在性別轉換上有複雜的表現。__slist_node繼承自__slist_node_base,__slist_iterator繼承自__slist_iterator_base。
struct __slist_node_base
{
__slist_node_base* next;
};
template <class T>
struct __slist_node : public __slist_node_base
{
T data;
};
2、slist迭代器
struct __slist_iterator_base
{
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef forward_iterator_tag iterator_category;
__slist_node_base* node;
__slist_iterator_base(__slist_node_base* x) : node(x) {}
void incr() { node = node->next; }
bool operator==(const __slist_iterator_base& x) const {
return node == x.node;
}
bool operator!=(const __slist_iterator_base& x) const {
return node != x.node;
}
};
template <class T, class Ref, class Ptr>
struct __slist_iterator : public __slist_iterator_base
{
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
typedef __slist_iterator<T, Ref, Ptr> self;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __slist_node<T> list_node;
__slist_iterator(list_node* x) : __slist_iterator_base(x) {}
__slist_iterator() : __slist_iterator_base(0) {}
__slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}
reference operator*() const { return ((list_node*) node)->data; }
pointer operator->() const { return &(operator*()); }
self& operator++()
{
incr();
return *this;
}
self operator++(int)
{
self tmp = *this;
incr();
return tmp;
}
};
3、slist資料結構
初始化的slist就一個head節點物件,head沒有data資料成員只有一個next成員,head.next=0。
template <class T, class Alloc = alloc>
class slist
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef __slist_iterator<T, T&, T*> iterator;
typedef __slist_iterator<T, const T&, const T*> const_iterator;
private:
typedef __slist_node<T> list_node;
typedef __slist_node_base list_node_base;
typedef __slist_iterator_base iterator_base;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
static list_node* create_node(const value_type& x) {
list_node* node = list_node_allocator::allocate();
__STL_TRY {
construct(&node->data, x);
node->next = 0;
}
__STL_UNWIND(list_node_allocator::deallocate(node));
return node;
}
static void destroy_node(list_node* node) {
destroy(&node->data);
list_node_allocator::deallocate(node);
}
private:
list_node_base head;
public:
slist() { head.next = 0; }
slist(size_type n, const value_type& x) { fill_initialize(n, x); }
slist(int n, const value_type& x) { fill_initialize(n, x); }
slist(long n, const value_type& x) { fill_initialize(n, x); }
explicit slist(size_type n) { fill_initialize(n, value_type()); }
template <class InputIterator>
slist(InputIterator first, InputIterator last) {
range_initialize(first, last);
}
slist(const_iterator first, const_iterator last) {
range_initialize(first, last);
}
slist(const value_type* first, const value_type* last) {
range_initialize(first, last);
}
slist(const slist& L) { range_initialize(L.begin(), L.end()); }
slist& operator= (const slist& L);
~slist() { clear(); }
public:
iterator begin() { return iterator((list_node*)head.next); }
const_iterator begin() const { return const_iterator((list_node*)head.next);}
iterator end() { return iterator(0); }
const_iterator end() const { return const_iterator(0); }
size_type size() const { return __slist_size(head.next); }
size_type max_size() const { return size_type(-1); }
bool empty() const { return head.next == 0; }
void swap(slist& L)
{
list_node_base* tmp = head.next;
head.next = L.head.next;
L.head.next = tmp;
}
public:
reference front() { return ((list_node*) head.next)->data; }
const_reference front() const { return ((list_node*) head.next)->data; }
void push_front(const value_type& x) {
__slist_make_link(&head, create_node(x));
}
void pop_front() {
list_node* node = (list_node*) head.next;
head.next = node->next;
destroy_node(node);
}
}
4、slist元素操作
(1)push_front
inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
__slist_node_base* new_node)
{
new_node->next = prev_node->next;
prev_node->next = new_node;
return new_node;
}
void push_front(const value_type& x) {
__slist_make_link(&head, create_node(x));
}
(2)pop_front
void pop_front() {
list_node* node = (list_node*) head.next;
head.next = node->next;
destroy_node(node);
}
(3)erase_after
list_node_base* erase_after(list_node_base* pos) {
list_node* next = (list_node*) (pos->next);
list_node_base* next_next = next->next;
pos->next = next_next;
destroy_node(next);
return next_next;
}
(4)insert_after
iterator insert_after(iterator pos, const value_type& x) {
return iterator(_insert_after(pos.node, x));
}
list_node* _insert_after(list_node_base* pos, const value_type& x) {
return (list_node*) (__slist_make_link(pos, create_node(x)));
}
inline __slist_node_base* __slist_make_link(__slist_node_base* prev_node,
__slist_node_base* new_node)
{
new_node->next = prev_node->next;
prev_node->next = new_node;
return new_node;
}
相關文章
- 連結串列 - 單向連結串列
- 棧_單向連結串列
- 12.19單向連結串列
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- 簡單的單向連結串列
- 佇列_單向連結串列佇列
- 單向迴圈連結串列
- 單向連結串列的建立
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- 連結串列-雙向連結串列
- 單向連結串列介面設計
- go 實現單向連結串列Go
- 連結串列-雙向通用連結串列
- 連結串列-雙向非通用連結串列
- 單向迴圈連結串列大綱
- 畫江湖之資料結構【第一話:連結串列】單向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 單向連結串列資料結構
- 雙向連結串列
- Python實現單向連結串列詳解Python
- 單向迴圈連結串列的介面程式
- 單向迴圈連結串列的實現
- 連結串列-單連結串列實現
- 設計單向迴圈連結串列的介面
- 單連結串列
- 資料結構之php實現單向連結串列資料結構PHP
- 資料結構-單連結串列、雙連結串列資料結構
- 演算法與資料結構-連結串列((linked-list)-Java實現單向連結串列演算法資料結構Java
- C語言單向連結串列的增刪操作C語言
- c/c++ 線性表之單向連結串列C++
- Java實現單向連結串列基本功能Java
- 簡單介紹python中的單向連結串列實現Python
- 線性表中的單向連結串列的簡單操作
- 實現雙向連結串列
- 【資料結構與演算法學習】線性表(順序表、單連結串列、雙向連結串列、迴圈連結串列)資料結構演算法
- 資料結構-2.單向連結串列的實現資料結構
- 單向迴圈連結串列——查詢、刪除、插入結點
- 資料結構實驗之連結串列九:雙向連結串列資料結構