完成伪标准:用伪迭代器列表完成mylist.h,一起写的声明和定义。
模板如下:
template<class T>
class list {
public:
struct listelem; // forward declarations
class iterator;
list();
list(size_t n_elements, const T& c);
list(const list& x);
list(iterator b, iterator e);
~list();
iterator begin() const;
iterator end() const;
size_t size();
void push_front(const T& c);
void push_back(const T& c);
void pop_front();
void pop_back();
iterator insert(iterator position, const T& val);
iterator erase (iterator position);
bool empty() const;
T& front();
T& back();
void clear();
friend ostream& operator << (ostream& out, const list& x);
struct listelem { // list cell
T data;
listelem *next, *prev;
listelem(const T& s, listelem* n, listelem* p); // suggest u to use the constructor
};
class iterator {
public:
friend class list; // suggest u to use friend class
explicit iterator(listelem* p = 0);
iterator(const iterator& other) ;
iterator& operator ++ ();
iterator& operator -- ();
iterator operator ++ (int);
iterator operator -- (int);
listelem* operator -> ();
T& operator * ();
// u can use iterator as listelem* sometimes
operator listelem * () {return ptr;} // conversion;
private:
listelem* ptr; // current listelem or 0;
};
private:
iterator h, t; // head and tail
};
Sample input:
4
1 2 3 4
Sample output:
test size
0
empty
test push and pop
[ 1 ]
[ ]
[ 1 ]
[ ]
[ 1 ]
[ ]
[ 1 ]
8
[ 4 3 2 1 1 2 3 4 ]
[ 2 1 1 2 3 ]
front : 2
back : 3
not empty
test begin and end
2 1 1 2 3
test insert and erase and ++ --
100
200
[ 100 2 1 1 2 3 200 ]
1
1
[ 100 1 2 3 200 ]
[ 99 101 100 1 2 3 200 ]
test constructor
[ 9 9 9 9 9 ]
[ 90 101 100 1 2 3 200 ]
[ 90 101 100 1 2 3 200 ]
[ 90 101 100 ]
mylist:
#include <iostream>
#include <cassert>
#include <string>
using namespace std;
template<class T>
class list {
public:
struct listelem; // forward declarations
class iterator;
list() {
h.ptr = t.ptr = 0;
} // construct the empty list
list(size_t n_elements, const T& c) {
h.ptr = t.ptr = 0;
for ( size_t i = 0; i < n_elements; ++i )
push_front(c);
}
list(const list& x) {
list::iterator r = x.begin();
h.ptr = t.ptr = 0;
while (r != 0) {
push_back(*r++);
}
}
list(iterator b, iterator e) {
h.ptr = t.ptr = 0;
while (b != e) {
push_back(*b++);
}
}
~list() { clear(); }
iterator begin() const { return h; }
iterator end() const {
iterator temp = t;
return (temp.ptr == 0 ? iterator(0) : ++temp);
}
size_t size() {
size_t count = 0;
iterator temp = h;
while (temp != end()) {
temp++;
count++;
}
return count;
}
void push_front(const T& c) {
listelem* temp = new listelem(c, h, 0);
if (h.ptr != 0) { // was a nonempty list
h->prev = temp;
h.ptr = temp;
} else { // was an empty list
h.ptr = t.ptr = temp;
}
}
void push_back(const T& c) {
listelem* temp = new listelem(c, 0, t);
if (t != 0) { // was a nonempty list
t->next = temp;
t.ptr = temp;
} else { // was an empty list
h.ptr = t.ptr = temp;
}
}
void pop_front() {
listelem* temp = h.ptr;
if (h.ptr != 0) {
if (h.ptr == t.ptr) t.ptr = 0;
h.ptr = h->next;
if (h.ptr != 0) h->prev = 0;
delete temp;
}
}
void pop_back() {
listelem* temp = t.ptr;
if (t.ptr != 0) {
if (h.ptr == t.ptr) h.ptr = 0;
t.ptr = t->prev;
if (t.ptr != 0) t->next = 0;
delete temp;
}
}
iterator insert(iterator position, const T& val) {
listelem* p = position.ptr;
if (p == 0) {
// p == end()
push_back(val);
return t;
} else if (p->prev == 0) {
// p == begin()
push_front(val);
return begin();
} else {
listelem* temp = new listelem(val, p, p->prev);
p->prev = temp;
temp->prev->next = temp;
return iterator(temp);
}
}
iterator erase(iterator position) {
listelem* temp = position.ptr;
if (temp == h) {
// temp == begin();
pop_front();
return h;
}
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
listelem* re = temp->next;
delete temp;
return iterator(re);
}
bool empty() const { return h.ptr == 0; }
T& front() { return *h; }
T& back() { return *t; }
void clear() {
while (h.ptr != 0) {
pop_front();
}
h.ptr = t.ptr = 0;
}
friend ostream& operator << (ostream& out, const list& x) {
list<T>::iterator p = x.begin();
out << "[ ";
while (p != 0) {
out << *p << " ";
++p; // advances iterator using next
}
out << "]";
return out;
}
struct listelem { // list cell
T data;
listelem *next, *prev;
listelem(const T& s, listelem* n, listelem* p) \
: data(s), next(n), prev(p) {}
};
// scopeed within class list
class iterator {
public:
friend class list;
explicit iterator(listelem* p) : ptr(p) {}
iterator() : ptr(0) {}
iterator& operator++() {
ptr = ptr->next;
return *this;
}
iterator& operator--() {
ptr = ptr->prev;
return *this;
}
iterator operator++(int) {
iterator temp = *this;
ptr = ptr->next;
return temp;
}
iterator operator--(int) {
iterator temp = *this;
ptr = ptr->prev;
return temp;
}
listelem* operator -> () { return ptr; }
T& operator * () { return ptr->data; }
operator listelem * () { return ptr; } // conversion
private:
listelem* ptr; // current listelem or 0;
};
private:
iterator h, t; // head and tail
};