微软的VS208所使用的PJ STL(注1)中的list是双链表,但在某些场合,一个轻量级的单链表会更加合适。单链表非常常见,这里就不去细说了,本文的slist(single linked list)单链表实现了链表的基本功能,如有需要,以后还会扩充的。slist单链表(带头结点)的示意图如下所示:
完整的C++代码如下:
- //带头结点的单链表
- //by MoreWindows( http://blog.csdn.net/MoreWindows )
- template<class T>
- struct Node
- {
- T val;
- Node *next;
- Node(T &n)
- {
- this->val = n;
- this->next = NULL;
- }
- };
- template<class T>
- class slist
- {
- public:
- slist();
- ~slist();
- void push_front(T &t);
- bool find(T &t);
- bool remove(T &t);
- bool removeAll(T &t);
- void clear();
- int size();
- public:
- int m_nListDataCount;
- Node<T> *m_head;
- };
- template<class T>
- slist<T>::slist()
- {
- m_head = NULL;
- m_nListDataCount = 0;
- }
- template<class T>
- slist<T>::~slist()
- {
- Node<T> *p, *pnext;
- for (p = m_head; p != NULL; p = pnext)
- {
- pnext = p->next;
- free(p);
- }
- m_nListDataCount = 0;
- }
- template<class T>
- void slist<T>::push_front(T &t)
- {
- Node<T> *pNode = (Node<T> *)malloc(sizeof(Node<T>));
- pNode->val = t;
- pNode->next = m_head;
- m_head = pNode;
- m_nListDataCount++;
- }
- template<class T>
- bool slist<T>::find(T &t)
- {
- for (Node<T> *p = m_head; p != NULL; p = p->next)
- if (p->val == t)
- return true;
- return false;
- }
- template<class T>
- int slist<T>::size()
- {
- return m_nListDataCount;
- }
- //删除链表中第一个值为t的结点
- template<class T>
- bool slist<T>::remove(T &t)
- {
- Node<T> *pNode, *pPreNode;
- pPreNode = pNode = m_head;
- while (pNode != NULL)
- {
- if (pNode->val == t)
- {
- if (pPreNode != pNode)
- pPreNode->next = pNode->next;
- else
- m_head = NULL;
- free(pNode);
- m_nListDataCount--;
- return true;
- }
- pPreNode = pNode;
- pNode = pNode->next;
- }
- return false;
- }
- //会删除链表中所有值为t的结点
- template<class T>
- bool slist<T>::removeAll(T &t)
- {
- bool flagDeleteNode = false;
- Node<T> *pNode, *pPreNode;
- pPreNode = pNode = m_head;
- while (pNode != NULL)
- {
- if (pNode->val == t)
- {
- pPreNode->next = pNode->next;
- free(pNode);
- pNode = pPreNode->next;
- m_nListDataCount--;
- flagDeleteNode = true;
- }
- else
- {
- pPreNode = pNode;
- pNode = pNode->next;
- }
- }
- return flagDeleteNode;
- }
- template<class T>
- void slist<T>::clear()
- {
- Node<T> *cur = m_head;
- while (cur != NULL)
- {
- Node<T> *next = cur->next;
- free(cur);
- cur = next;
- }
- m_head = NULL;
- }
该slist完成了从头部插入,查找和删除数据等链表的基本操作,下一篇将使用这个slist来完成一个哈希表,请关注下一篇——《STL系列之九 探索hash_set》
注1.STL分为很多版本,微软的VS系列使用的是PJ STL。而《STL源码剖析》书中主要使用SGI STL。