list

Dev.Write 2013. 4. 12. 11:03 Posted by zetz
List.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#pragma once
 
/**!
    * Double linked-list
    - except to "const" type iterator functions.
*/
 
template<class Data>
class List
{
    struct Node
    {
        Node(const Data& data_) : prev(0), next(0), data(data_) {}
        Node*   prev;
        Node*   next;
        Data    data;
    };
 
public:
    class Iterator
    {
        friend class List<Data>;
    public:
        Iterator() : m_Node(0) {}
        Iterator& operator++() { m_Node = m_Node->next; return *this; };
        Iterator& operator--() { m_Node = m_Node->prev; return *this; };
 
        Iterator& operator++(int) { Iterator tmp = *this; m_Node = m_Node->next; return tmp; };
        Iterator& operator--(int) { Iterator tmp = *this; m_Node = m_Node->prev; return tmp; };
 
        bool operator ==(const Iterator& rhs) const { return m_Node == rhs.m_Node; }
        bool operator !=(const Iterator& rhs) const { return m_Node != rhs.m_Node; }
 
        Data&   operator*() { return m_Node->data; }
        Data*   operator->() { return &m_Node->data; }
    private:
        explicit Iterator(Node* n) : m_Node(n) {}
        Node*       m_Node;
    };
 
    List() : m_Head(0), m_Tail(0), m_Size(0) {}
    List(const List<Data>& rhs) : m_Head(rhs.m_Head), m_Tail(rhs.m_Tail), m_Size(rhs.m_Size) {}
    ~List() {
        clear();
    }
 
    void    operator=(const List<Data>& rhs);
 
    //! size
    size_t      size() const { return m_Size; }
    void        clear();
    bool        empty() const { return (m_Head == 0); };
    void        push_back(const Data& data);
    void        push_front(const Data& data);
 
    //! access iterator
    Iterator    begin() { return Iterator(m_Head); }
    Iterator    end() { return Iterator(0); }
    Iterator    back() const { return Iterator(m_Tail); };
 
    //! algorithm
    void        insert(const Iterator& itr, const Data& data);
    Iterator    erase(Iterator& itr);
    Iterator    find(const Data& data);
    Iterator    find(const Data& data, const Iterator& where);
     
    template<class Predicator>
    void        sort(Predicator compare);
 
private:
    Node*       m_Head;
    Node*       m_Tail;
    size_t      m_Size;
};
 
#include "List.inl"
List.inl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
template<class Data>
void List<Data>::operator=( const List<Data>& rhs )
{
    if (&rhs == this)
        return;
 
    clear();
 
    Node* node = rhs.m_Head;
    while (node)
    {
        push_back(node->data);
        node = node->next;
    }
}
 
 
template<class Data>
void List<Data>::clear()
{
    while (m_Head)
    {
        //< save next node
        Node* next = m_Head->next;
        delete m_Head;
        m_Head = next;
    }
    m_Tail = 0;
    m_Size = 0;
}
 
 
template<class Data>
void List<Data>::push_back( const Data& data )
{
    Node* node = new Node(data);
    ++m_Size;
    if (m_Head == NULL)
        m_Head = node;
    node->prev = m_Tail;
    if (m_Tail != NULL)
        m_Tail->next = node;
    m_Tail = node;
}
 
 
template<class Data>
void List<Data>::push_front( const Data& data )
{
    Node* node = new Node(data);
    ++m_Size;
    if (m_Head == NULL) {
        m_Head = node;
        m_Tail = node;
    } else {
        node->next = m_Head;
        m_Head->prev = node;
        m_Head = node;
    }
}
 
 
template<class Data>
void List<Data>::insert( const Iterator& itr, const Data& data )
{
    Node* node = new Node(data);
    node->next = itr.m_Node->next;
 
    if (itr.m_Node->next)
        itr.m_Node->next->prev = node;
 
    node->prev = itr.m_Node;
    itr.m_Node->next = node;
    ++m_Size;
 
    if (itr.m_Node == m_Tail)
        m_Tail = node;
 
}
 
template<class Data>
typename List<Data>::Iterator List<Data>::erase( Iterator& itr )
{
    List<Data>::Iterator ret(itr);
    if (ret == end()) return ret;
    ++ret;
    if (itr.m_Node == m_Head) {
        m_Head = itr.m_Node->next;
    } else {
        itr.m_Node->prev->next = itr.m_Node->next;
    }
 
    if (itr.m_Node == m_Tail) {
        m_Tail = itr.m_Node->prev;
    } else {
        itr.m_Node->next->prev = itr.m_Node->prev;
    }
 
    delete itr.m_Node;
    itr.m_Node = NULL;
    --m_Size;
 
    return ret;
}
 
template<class Data>
typename List<Data>::Iterator List<Data>::find( const Data& data )
{
    return find(data, begin());
}
 
template<class Data>
typename List<Data>::Iterator List<Data>::find( const Data& data, const Iterator& where )
{
    Node* node = where.m_Node;
    while (node)
    {
        if (node->data == data)
            break;
        node = node->next;
    }
    return Iterator(node);
}
 
 
template<class Data>
template<class Predicator>
void List<Data>::sort( typename Predicator compare )
{
    if (m_Size< 2) return;
 
    for (Node* i= m_Head->next; i != NULL; i = i->next) {
        Node* dst = NULL;
        for (Node* j= i->prev; j != NULL; j = j->prev) {
            if (compare(j->data, i->data)) break;
            dst = j;
        }
 
        if (dst== NULL) continue;
 
        Node* src = i;
        //printf("src(%d) --> dst(%d)\n", src->data, dst->data);
 
        //!unlink src node
        src->prev->next = src->next;
 
        if (src == m_Tail) {
            m_Tail = src->prev;
        } else {
            src->next->prev = src->prev;
        }
 
        //! link dst node
        src->prev = dst->prev;
 
        if (dst->prev)
            dst->prev->next = src;
 
        src->next = dst;
        dst->prev = src;
 
        if (dst == m_Head)
            m_Head = src;
    }
}

'Dev.Write' 카테고리의 다른 글

a timer using boost  (0) 2013.08.02
boost::xml_parser wrapper  (1) 2013.06.12
quick sort, bouble sort  (1) 2013.03.25
insert sort, b-search  (0) 2013.03.07
[Python] os 모듈  (0) 2011.10.21