#ifndef __LINKEDLISTPRACTICE__H__ #define __LINKEDLISTPRACTICE__H__ 1 namespace FengChen ... { // template for double link list template <class Type> class LinkedList; template <class T> std::ostream& operator<<(std::ostream& os, const LinkedList<T>& L) ...{ os << "< "; ListNode<T> *p; if(L.Size() < 1) os << "Empty!"; for (p = L.m_Head->next ; p != 0; p = p->next) os << p->item << " "; os <<">"; return os; } template <class Type> class ListNode ...{ friend class LinkedList<Type>; // needs access to item and next friend std::ostream& operator<< <Type>(std::ostream&, const LinkedList<Type>&); ListNode():next(0), previous(0) ...{} // private class: no public section ListNode(const Type &t): item(t), next(0), previous(0)...{} Type item; ListNode *next; ListNode *previous; }; template <class Type> class LinkedList...{ friend std::ostream& operator<< <Type>(std::ostream&, const LinkedList<Type>&); public: LinkedList():m_Head(new ListNode<Type>), m_Tail(m_Head),m_size(0)...{} LinkedList(const LinkedList &List): m_Head(new ListNode<Type>), m_Tail(m_Head), m_size(0) ...{copy_elems(List);} LinkedList(const Type* start, int Size): m_Head(new ListNode<Type>), m_Tail(m_Head), m_size(0) ...{ copy_elems (start,Size); } void Assign(const Type* start, int Size) ...{ this->MakeEmpty(); copy_elems (start, Size); } void MakeEmpty() ...{ ListNode<Type>* node = m_Head->next; ListNode<Type>* temp = 0; m_Head->next = 0; while( node != 0 ) ...{ temp = node->next; delete node; node = temp; } m_Tail = m_Head; m_size = 0; } inline bool IsEmpty() const ...{ return m_size != 0; } inline int IsLast(ListNode<Type>* p)...{ return IsEmpty() && p == m_Tail; } ListNode<Type>* Find(const Type& X) ...{ ListNode<Type>* node = m_Head->next; while (node != 0 && node->item != X) node= node->next; return node; } ListNode<Type>* FindLast (const Type& X) ...{ ListNode<Type>* node = m_Tail; while(node != m_Head && node->item != X ) node = node->previous; } void Delete(Type X) ...{ ListNode<Type>* node = Find(X); if(node != 0) ...{ node->previous->next = node->next; node->next->previous = node->previous; if(node == m_Tail) m_Tail = node->previous; delete node; } m_size--; } void Push(Type X) ...{ Insert(X, m_Tail); } void Insert(Type X, ListNode<Type>* p) ...{ ListNode<Type>* node = new ListNode<Type>(X); if(node == 0) throw std::runtime_error("Out of space!"); node->next = p->next; node->previous = p; if(p->next != 0) p->next->previous = p; else m_Tail = node; p->next = node; m_size++; } Type Value(ListNode<Type>* p) ...{ return p->item;} ListNode<Type>* Previous(ListNode<Type>* p) ...{ return p->previous; } ListNode<Type>* Next(ListNode<Type>* p) ...{ return p->next; } Type& Front() ...{ if(m_size == 0) throw std::runtime_error("Empty List!"); return m_Head->next->item; } Type& Tail() ...{ if(m_size == m_Head) throw std::runtime_error("Empty List!"); return m_Tail->item; } void Inverse() ...{ if(m_size < 1) return; ListNode<Type>* pFirst = m_Head->next; // First element while(m_Tail != pFirst) ...{ ListNode<Type>* node = m_Tail; m_Tail = node->previous; m_Tail->next = 0; node->previous = pFirst->previous; node->next = pFirst; pFirst->previous->next = node; pFirst->previous = node; } } int Size() const ...{ return m_size; } LinkedList<Type>& operator=(const LinkedList& rhs) ...{ copy_elems (rhs); } ~LinkedList<Type>() ...{ MakeEmpty (); delete m_Head; m_Head = 0; } private: ListNode<Type> *m_Head; ListNode<Type> *m_Tail; int m_size; void copy_elems(const Type* start, int Size) ...{ assert(Size >= 0); int idx = 0; while(idx < Size) Push (start[idx++]); } void copy_elems(const LinkedList& List) ...{ MakeEmpty (); if(List.Size () == 0 ) return; ListNode<Type>* src = List.m_Head->next; while(src != 0) ...{ this->Push(src->item); src = src->next; } } };} #endif