为了方便,我把myList这个类的函数的声明和定义全都写在myList这个头文件中,这样是一种不好的编程习惯,并不鼓励这么做。
//
// myList.h:
// C++
//
// Created by 舒俊淮 on 16/7/7.
// Copyright © 2016年 Shujh. All rights reserved.
//
#include <iostream>
using namespace std;
template<class T>
class list {
public:
struct listelem;
class iterator;
list() {
h.ptr = NULL;
t.ptr = NULL;
End.ptr = NULL;
_size = 0;
}
list(size_t n_elements, const T& c) {
h.ptr = NULL;
t.ptr = NULL;
_size = 0;
for (int i = 0; i < n_elements; ++i)
push_front(c);
End = new listelem(0, NULL, t);
t->next = End;
}
list(const list& x) {
h.ptr = NULL;
t.ptr = NULL;
_size = 0;
iterator temp = x.t;
for (int i = 0; i < x.size(); ++i) {
push_front(temp->data);
temp = temp->prev;
}
End = new listelem(0, NULL, t);
t->next = End;
}
list(iterator b, iterator e) {
h.ptr = NULL;
t.ptr = NULL;
_size = 0;
iterator temp = b;
while (temp != e) {
push_back(temp->data);
temp = temp->next;
}
End = new listelem(0, NULL, t);
t->next = End;
}
~list() {
clear();
}
iterator begin() const {return h;}
iterator end() const {return End;}
int size() const {return _size;}
void push_front(const T& c) {
insert(h, c);
}
void push_back(const T& c) {
insert(End, c);
}
void pop_front() {
erase(h);
}
void pop_back() {
erase(t);
}
iterator insert(iterator position, const T& val) {
if (position == h) {
if (_size == 0) {
h = new listelem(val);
t = h;
_size++;
return h;
} else {
listelem* temp = new listelem(val, h, NULL);
h->prev = temp;
h = temp;
_size++;
iterator s(temp);
return s;
}
} else if (position == t) {
if (_size == 0) {
t = new listelem(val);
h = t;
_size++;
return t;
} else {
listelem* temp = new listelem(val, t, t->prev);
t->prev->next = temp;
t->prev = temp;
_size++;
iterator s(temp);
return s;
}
} else if (position == End) {
if (_size == 0) {
t = new listelem(val);
h = t;
_size++;
return t;
} else {
listelem* temp = new listelem(val, NULL, t);
t->next = temp;
t = temp;
_size++;
iterator s(temp);
return s;
}
} else {
listelem* temp = new listelem(val, position, position->prev);
position->prev->next = temp;
position->next = temp;
_size++;
iterator s(temp);
return s;
}
}
iterator erase(iterator position) {
if (position == h) {
if (_size == 0) {iterator temp(NULL); return temp;}
if (_size == 1) {
delete h.ptr;
h.ptr = NULL;
t.ptr = NULL;
_size--;
iterator temp(NULL);
return temp;
} else {
iterator temp = h;
h = h->next;
h->prev = NULL;
delete temp.ptr;
_size--;
return h;
}
} else if (position == t) {
if (_size == 0) {iterator temp(NULL); return temp;}
if (_size == 1) {
delete t.ptr;
h.ptr = NULL;
t.ptr = NULL;
_size--;
iterator temp(NULL);
return temp;
} else {
iterator temp = t;
t = t->prev;
t->next = NULL;
delete temp.ptr;
_size--;
iterator tp(NULL);
return tp;
}
} else {
iterator temp = position;
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
listelem* re = temp->next;
delete temp.ptr;
_size--;
iterator r(re);
return r;
}
}
bool empty() const {return _size == 0;}
T& front() {return *h;}
T& back() {return *t;}
void clear() {
while (_size) {pop_front();}
delete End.ptr;
}
friend ostream& operator << (ostream& out, const list& x) {
out << "[ ";
int n = x.size();
iterator temp = x.h;
while (n--) {
out << temp->data << " ";
temp = temp->next;
}
out << "]";
return out;
}
struct listelem {
T data;
listelem *next, *prev;
listelem(const T& s, listelem* n = NULL, listelem* p = NULL)
: data(s), next(n), prev(p) {}
};
class iterator {
public:
friend class list;
explicit iterator(listelem* p = 0): ptr(p) {}
iterator(const iterator& other) {ptr = other.ptr;}
iterator& operator ++() {
ptr = ptr->next;
return *this;
}
iterator& operator --() {
ptr = ptr->prev;
return *this;
}
iterator operator ++(int n) {
iterator temp(ptr);
ptr = ptr->next;
return temp;
}
iterator operator --(int n) {
iterator temp(ptr);
ptr = ptr->prev;
return temp;
}
iterator& operator=(listelem* other) {
ptr = other;
return *this;
}
listelem* operator -> () {return ptr;}
T& operator *() {return ptr->data;}
operator listelem * () {return ptr;}
private:
listelem* ptr;
};
private:
iterator h, t;
iterator End;
int _size;
};
测试函数:
//test.cpp:
#include <iostream>
#include <string>
#include "myList.h"
using namespace std;
int main() {
list<int> li;
cout << "test size" << endl;
cout << li.size() << endl;
cout << (li.empty() ? "empty" : "not empty") << endl;
int n; // n >= 3
cout << "test push and pop" << endl;
li.push_back(1);
cout << li << endl;
li.pop_back();
cout << li << endl;
li.push_front(1);
cout << li << endl;
li.pop_front();
cout << li << endl;
li.push_back(1);
cout << li << endl;
li.pop_front();
cout << li << endl;
li.push_front(1);
cout << li << endl;
li.pop_back();
cin >> n;
for (int i = 0; i < n; i++) {
int tmp;
cin >> tmp;
li.push_back(tmp);
li.push_front(tmp);
}
cout << li.size() << endl;
cout << li << endl;
li.pop_back();
li.pop_front();
li.pop_front();
cout << li << endl;
cout << "front : " << li.front() << endl;
cout << "back : " << li.back() << endl;
cout << (li.empty() ? "empty" : "not empty") << endl;
cout << "test begin and end" << endl;
list<int>::iterator it = li.begin();
while (it != li.end()) {
cout << it->data << " ";
it++;
}
cout << endl;
cout << "test insert and erase and ++ --" << endl;
it = li.begin();
cout << *(li.insert(it, 100)) << endl;
it = li.end();
cout << *(li.insert(it, 200)) << endl;
cout << li << endl;
it = li.begin();
cout << *(li.erase(++it)) << endl;
it = li.begin();
it++;
cout << *(li.erase(it)) << endl;
cout << li << endl;
it = li.begin();
it++;
it--;
li.insert(it, 101);
it = li.begin();
++it;
--it;
li.insert(it, 99);
cout << li << endl;
it = li.begin();
*it = 90;
cout << "test constructor" << endl;
list<int> li2(5, 9);
list<int> li3(li);
it = li.begin();
list<int>::iterator it2 = it;
++(++(++it2));
list<int> li4(li.begin(), li.end());
list<int> li5(it, it2);
cout << li2 << endl;
cout << li3 << endl;
cout << li4 << endl;
cout << li5 << endl;
return 0;
}