概述
该单链表的实现具有迭代器(一个嵌套类)以及,增、删、改、查、反转操作,所有关于指针的操作均隐藏在迭代器里。
代码实现
template <class Object>
class LinkList {
private:
struct Node {
Object data;
struct Node * next;
Node(const Object & d = Object(), Node *p = nullptr) : data(d), next(p) { }
};
public:
class const_iterator {
public:
const_iterator() : current(nullptr) { }
const Object & operator*() const { return retrieve(); }
const_iterator & operator++()
{
current = current != nullptr ? current->next : nullptr;
return *this;
}
const_iterator operator++(int)
{
const_iterator old = *this;
++(*this);
return old;
}
bool operator==(const const_iterator & rhs) const
{
return current == rhs.current;
}
bool operator!=(const const_iterator & rhs) const
{
return !(*this == rhs);
}
protected:
Node * current;
Object & retrieve() const { return current->data; }
const_iterator(Node * p) : current(p) { }
friend class LinkList<Object>;
};
class iterator : public const_iterator {
public:
iterator() { }
Object & operator*()
{
return const_iterator::retrieve();
}
const Object & operator*() const
{
return const_iterator::operator*();
}
iterator & operator++ ()
{
const_iterator::current = const_iterator::current != nullptr ? const_iterator::current->next : nullptr;
return *this;
}
iterator operator++(int)
{
iterator old = *this;
++(*this);
return old;
}
protected:
iterator(Node *p) : const_iterator(p) { }
friend class LinkList<Object>;
};
public:
LinkList() { init();}
LinkList(const LinkList & rhs) { init(); *this = rhs; }
~LinkList()
{
clear();
theSize = 0;
delete head;
}
const LinkList & operator=(const LinkList & rhs) {
if (this == &rhs) {
return *this;
}
clear();
iterator it(head);
for (const_iterator itr = rhs.begin(); itr != rhs.end(); itr++) {
it = insert(it, *itr);
}
return *this;
}
void clear() {
while (!empty()) {
pop_front();
}
}
iterator begin() { return iterator(head->next); }
const_iterator begin() const { return const_iterator(head->next); }
iterator end() { return iterator(); }
const_iterator end() const { return const_iterator(); }
int size() const { return theSize; }
bool empty() const { return size() == 0; }
iterator insert(iterator pre, const Object &X) {
if (nullptr == pre.current) {
throw std::runtime_error("insert: nullptr");
}
Node * p = new Node(X, pre.current->next);
pre.current->next = p;
theSize++;
return iterator(p);
}
iterator findPre(const Object & X) {
iterator it(head);
while (it.current->next != nullptr && it.current->next->data != X) {
it++;
}
return it;
}
iterator find(const Object & X) {
iterator ret = findPre(X);
return ++ret;
}
void deleteEle(const Object & X) {
iterator it = findPre(X);
if (it.current->next != nullptr) {
iterator temp = it.current->next;
it.current->next = temp.current->next;
delete temp.current;
theSize--;
}
}
iterator erase(iterator it) {
Node * p = it.current;
if (nullptr == p) {
return iterator(nullptr);
}
iterator ret(p->next);
iterator pre_it = findPre(p->data);
if (pre_it.current->next != nullptr) {
pre_it.current->next = p->next;
}
delete p;
theSize--;
return ret;
}
iterator erase(iterator from, iterator to) {
iterator it(from);
for (; it != to;) {
it = erase(it);
}
return it;
}
void pop_front() {
erase(begin());
}
void push_front(const Object & X) {
insert(iterator(head), X);
}
void reverse(LinkList &L) {
if (empty()) return;
Node * pre = nullptr;
Node * cur = L.head->next;
while (cur != nullptr) {
Node * tmp = cur->next;
cur->next = pre;
pre = cur;
cur = tmp;
}
L.head->next = pre;
}
private:
int theSize;
Node * head;
void init()
{
theSize = 0;
head = new Node;
}
};
int main(int argc, char **argv)
{
{
LinkList<int> L;
LinkList<int>::iterator it;
try {
L.push_front(1);
L.push_front(2);
L.push_front(3);
L.push_front(3);
L.push_front(3);
L.push_front(4);
L.push_front(5);
L.push_front(7);
L.deleteEle(7);
L.deleteEle(700);
it = L.find(5);
if (it != L.end()) {
std::cout << "find " << *it << std::endl;
}
else {
std::cout << "Don't find\n";
}
L.reverse(L);
std::cout << "\nsize is " << L.size() << std::endl;
for (it = L.begin(); it != L.end();) {
std::cout << *it << " ";
if (3 == *it) {
it = L.erase(it);
}
else {
it++;
}
}
std::cout << std::endl;
std::cout << "\nsize is " << L.size() << std::endl;
for (LinkList<int>::const_iterator con_it = L.begin(); con_it != L.end(); con_it++) {
std::cout << *con_it << " ";
}
std::cout << std::endl;
L.pop_front();
std::cout << "\nsize is " << L.size() << std::endl;
for (LinkList<int>::const_iterator con_it = L.begin(); con_it != L.end(); con_it++) {
std::cout << *con_it << " ";
}
std::cout << std::endl;
L.erase(++L.begin(), L.end());
std::cout << "\nsize is " << L.size() << std::endl;
L.clear();
std::cout << "\nsize is " << L.size() << std::endl;
}
catch (std::runtime_error &e) {
std::cerr << e.what() << std::endl;
}
}
return 0;
}
参考文献
数据结构与算法分析第三版(C++)
本文详细介绍了使用C++实现单链表的过程,包括迭代器的使用,以及增、删、改、查、反转等操作。通过具体的代码示例,展示了如何在单链表中进行元素的插入、查找、删除和遍历。
944

被折叠的 条评论
为什么被折叠?



