1.Linked List
Each node in a linked list points to the next node in the list.
2.Singly Linked Lists
Each node in the list points only to the next node.
3.The SListNode Class
two data members: m_data and m_next;
[Data]
template <class Datatype>
class SListNode
{
public:
Datatype m_data;
SListNode<Datatype>* m_next;
};
create a list:
SListNode<int>* list = new SListNode<int>;
list->m_data = 10;
list->m_next = new SListNode<int>;
list->m_next->m_data = 20;
[InsertAfter Func]insert a node after the current node
This process has two steps:
1.Create a new node that points to the one after the current node.
2.Make the one before the current node point to the new node.
void InsertAfter(Datatype p_data)
{
SListNode<Datatype>* newnode = new SListNode<Datatype>;
newnode->m_data = p_data;
newnode->m_next = m_next;
m_next = newnode;
}
4.Iterators // 游标,迭代器
You need to have some way of moving through a linked list and accessing all of the nodes.
An iterator is simply a structure that allows you to move through a linked list from start to finish.An iterator basically points to a specific node in a list.
5.A linked list
I preferred to wrap the node structure into another class.
template <class Datatype>
class SLinkedList
{
public:
SListNode<Datatype>* m_head;
SListNode<Datatype>* m_tail;
int m_count;
};
[Cons & Des]
SLinkedList()
{
m_head = 0;
m_tail = 0;
m_count = 0;
}
~SLinkedList()
{
SListNode<Datatype>* itr = m_head;
SListNode<Datatype>* next;
while (itr != 0)
{
next = itr->m_next;
delete itr;
itr = next;
}
}
[Append Func]
void Append(Datatype p_data)
{
if (m_head == 0)
{
m_head = m_tail = new SListNode<Datatype>;
m_head->m_data = p_data;
}
else
{
m_tail->InsertAfter(p_data);
m_tail = m_tail->m_next;
}
m_count ++;
}
[Prepend Func] add items to the beginning
void Prepend(Datatype p_data)
{
SListNode<Datatype>* newnode = new SListNode<Datatype>;
newnode->m_data = p_data;
newnode->m_next = m_head;
m_head = newnode;
if (m_tail == 0) m_tail = m_head;
m_count ++;
}
[RemoveHead Func] remove nodes from the beginning of a list
void RemoveHead()
{
SListNode<Datatype>* node = 0;
if (m_head != 0)
{
node = m_head->m_next;
delete m_head;
m_head = node;
if (m_head == 0)
m_tail = 0;
m_count --;
}
}
[RemoveTail]
void RemoveTail()
{
SListNode<Datatype>* node = m_head;
if (m_head != 0)
{
if (m_head == m_tail)
{
delete m_head;
m_head = m_tail = 0;
}
else
{
while (node->m_next != m_tail)
node = node->m_next;
m_tail = node;
delete node->m_next;
node->m_next = 0;
}
m_count --;
}
}
6.SListIterator Class
It contains two things: A pointer to the current node and a pointer to the list the node is in.
[Data]
template <class Datatype>
class SListIterator
{
public:
SListNode<Datatype>* m_node;
SLinkedList<Datatype>* m_list;
};
[Cons]
SListIterator(SLinkedList<Datatype>* p_list = 0, SListNode<Datatype>* p_node = 0)
{
m_list = p_list;
m_node = p_node;
}
[Start Func]resets the iterator to point to the very first node in the list
void Start()
{
if (m_list != 0)
m_node = m_list->m_head;
}
[Forth Func]
void Forth()
{
if (m_node != 0)
m_node = m_node->m_next;
}
[Item Func]
Datatype& Item()
{
return m_node->m_data;
}
[Valid]
bool Valid()
{
return (m_node != 0);
}
[GetIterator]generate a iterator
SListIterator<Datatype> GetIterator() // class SLinkedList
{
return SListIterator<Datatype>(this, m_head);
}
[Using Iterators]
SLinkedList<int> list;
list.Append(10);
list.Append(20);
list.Append(30);
SListIterator<int> itr = list.GetIterator();
for (itr.Start(); itr.Valid(); itr.Forth())
{
cout << itr.Item() << ", ";
}
itr.Start();
[Insert Func] inserts a node after an iterator
void Insert(SListIterator<Datatype>& p_iterator, Datatype p_data)
{
if (p_iterator.m_list != this)
return;
if (p_iterator.m_node != 0)
{
p_iterator.m_node->InsertAfter(p_data);
if (p_iterator.m_node == m_tail)
{
m_tail = p_iterator.m_node->m_next;
}
m_count ++;
}
else
{
Append(p_data);
}
}
[Remove]
void Remove(SListIterator<Datatype>& p_iterator)
{
SListNode<Datatype>* node = m_head;
if (p_iterator.m_list != this)
return;
if (p_iterator.m_node == 0)
return;
if (p_iterator.m_node == m_head)
{
p_iterator.Forth();
RemoveHead();
}
else
{
while (node->m_next != p_iterator.m_node)
node = node->m_next;
p_iterator.Forth();
if (node->m_next == m_tail)
{
m_tail = node;
}
delete node->m_next;
node->m_next = p_iterator.m_node;
}
m_count --;
}
7.Doubly Linked List
[Node Structure]
←previous data next→
8.Real-World Issues
Don't use linked lists for things that require little processing or things that will be created and destroyed quickly.