Department of Computer Science | Institute of Theoretical Computer Science | CADMO

Theory of Combinatorial Algorithms

Prof. Emo Welzl and Prof. Bernd Gärtner

// Programm: list.h // Doppelt verkettete Listen #include #include #include namespace ifm { // // ListElement: Die Elemente der Liste // class ListElement { public: ListElement(int x, ListElement* p, ListElement* n); int data; friend class List; friend class ListIterator; friend class ListConstIterator; friend std::ostream& operator<<(std::ostream& o, const List& l); private: ListElement* prev_; ListElement* next_; }; ListElement::ListElement(int x, ListElement* p, ListElement* n) : data(x), prev_(p), next_(n) {} // // Iterator Klassen // class ListIterator { public: typedef int value_type; typedef int* pointer; typedef int& reference; typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef ListIterator This; ListIterator(ListElement* p) : ptr_(p) {} friend bool operator==(const This& x, const This& y); int& operator*() const { return ptr_->data; } This& operator++() { ptr_ = ptr_->next_; return *this; } This operator++(int) { This t = *this; ++*this; return t; } This& operator--() { ptr_ = ptr_->prev_; return *this; } This operator--(int) { This t = *this; --*this; return t; } friend class List; private: ListElement* ptr_; }; bool operator==(const ListIterator& x, const ListIterator& y) { return x.ptr_ == y.ptr_; } bool operator!=(const ListIterator& x, const ListIterator& y) { return !(x == y); } class ListConstIterator { public: typedef int value_type; typedef int* pointer; typedef int& reference; typedef std::ptrdiff_t difference_type; typedef std::bidirectional_iterator_tag iterator_category; typedef ListConstIterator This; ListConstIterator(const ListElement* p) : ptr_(p) {} friend bool operator==(const This& x, const This& y); const int& operator*() const { return ptr_->data; } This& operator++() { ptr_ = ptr_->next_; return *this; } This operator++(int) { This t = *this; ++*this; return t; } This& operator--() { ptr_ = ptr_->prev_; return *this; } This operator--(int) { This t = *this; --*this; return t; } friend class List; private: const ListElement* ptr_; }; bool operator==(const ListConstIterator& x, const ListConstIterator& y) { return x.ptr_ == y.ptr_; } bool operator!=(const ListConstIterator& x, const ListConstIterator& y) { return !(x == y); } // // Die Liste // class List { public: typedef ListIterator iterator; typedef ListConstIterator const_iterator; List(); // POST: Initialisiert zu leerer Liste. ~List(); // POST: Alle Listenelemente geloescht. List(const List& l); // POST: Initialisiert zu l. List& operator=(const List&); // POST: Ersetzt durch l. iterator begin(); iterator end(); const_iterator begin() const; const_iterator end() const; void insert(int x, iterator i); // PRE: i ist aus [begin(),end()) // POST: fuege x vor i ein. void erase(iterator i); // PRE: i ist aus [begin(), end()) // POST: i aus Liste entfernt private: void append(const_iterator b, const_iterator e); // POST: die Elemente aus [b,e) wurden am Ende der Liste // eingefuegt, d.h. *[b,e) ist Suffix der Liste. void destroy(iterator b, iterator e); // POST: die Elemente aus [b,e) wurden geloescht, der belegte // Speicher wurde freigegeben. ListElement sentinel; }; // // Memberfunktionen von List // List::List() : sentinel(0, 0, 0) { sentinel.next_ = &sentinel; sentinel.prev_ = &sentinel; } List::~List() { destroy(begin(), end()); } List::List(const List& l) : sentinel(0, 0, 0) { sentinel.next_ = &sentinel; sentinel.prev_ = &sentinel; append(l.begin(), l.end()); } List& List::operator=(const List& l) { if (&l != this) { destroy(begin(), end()); append(l.begin(), l.end()); } return *this; } void List::append(const_iterator b, const_iterator e) { for (; b != e; ++b) insert(*b, end()); } void List::destroy(iterator b, iterator e) { while (b != e) { iterator d = b++; delete d.ptr_; } } List::const_iterator List::begin() const { return sentinel.next_; } List::const_iterator List::end() const { return &sentinel; } List::iterator List::begin() { return sentinel.next_; } List::iterator List::end() { return &sentinel; } void List::insert(int x, iterator i) // PRE: i ist aus [begin(),end()) // POST: fuege x vor i ein. { ListElement* ip = i.ptr_; ListElement* n = new ListElement(x, ip->prev_, ip); n->prev_->next_ = n; n->next_->prev_ = n; } void List::erase(iterator i) // PRE: i ist aus [begin(), end()) // POST: i aus Liste entfernt { ListElement* ip = i.ptr_; ip->prev_->next_ = ip->next_; ip->next_->prev_ = ip->prev_; delete ip; } std::ostream& operator<<(std::ostream& o, const List& l) { o << "("; for (List::const_iterator i = l.begin(); i != l.end(); ++i) o << *i << ","; return o << ")"; } } // namespace ifm