希望大家看过后对我自己写的这些笨方法提出意见,如果有问题也请及时指出,谢谢^^
Exercise 3.2 Swap two adjacent elements by adjusting only the links ( and not the data ) using
a. Singly linked list.
b. Doubly linked list
//single.hpp
#ifndef SINGLE_H__
#define SINGLE_H__
template<typename Object>
class SLList {
private:
class Node {
public:
Node(const Object& ob = Object(), Node* n = 0) :
data(ob), next(n) {}
public:
Node* next;
Object data;
};
public:
class const_iterator {
public:
const_iterator() : current(0) {}
const Object& operator*() const{ return retrieve(); }
const_iterator& operator++()
{
current = current->next;
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:
const_iterator(Node* p) : current(p) {}
Object& retrieve() const { return current->data; }
Node* current;
friend class SLList<Object>;
};
class iterator : public const_iterator {
public:
iterator(){}
Object& operator*() { return retrieve(); }
const Object& operator*() const { return retrieve(); }
iterator& operator++()
{
current = current->next;
return *this;
}
iterator& operator++(int)
{
iterator old = *this;
++(*this);
return old;
}
bool operator==(const iterator& rhs)
{ return current == rhs.current; }
bool operator!=(const iterator& rhs)
{ return !(*this == rhs); }
private:
iterator(Node* p) : const_iterator(p){}
friend class SLList<Object>;
};
public:
SLList() { init(); }
~SLList()
{
clear();
delete head;
delete tail;
}
SLList(const SLList& rhs)
{
init();
*this = rhs;
}
SLList& operator=( const SLList& rhs)
{
if(*this == rhs)
return *this;
clear();
for(const_iterator it = rhs.begin(); it != rhs.end(); ++it)
push_back(*it);
return *this;
}
public:
bool empty() { return theSize == 0; }
void clear()
{
while(!empty())
pop_front();
}
void pop_front()
{
Node* p = head->next;
head->next = head->next->next;
delete p;
--theSize;
}
void push_front(const Object& ob)
{
Node* p = head->next;
head->next = new Node(ob, p);
++theSize;
}
iterator begin(){ return iterator(head->next); }
const_iterator begin() const { return const_iterator(head->next); }
iterator end() { return iterator(tail); }
const_iterator end() const { return const_iterator(tail); }
Object& front() { return *begin(); }
const Object& front() const { return *begin(); }
void swapAdj(iterator it/*first, iterator second*/)
{
int cnt = 0;
Node* p = it.current;
iterator i = iterator(this->head);
while(i != it)
{
++i;
++cnt;
}
--cnt;
i = iterator(this->head);
while(cnt > 0)
{
++i;
--cnt;
}
Node* pi = i.current;
pi->next = p->next;
p->next = pi->next->next;
pi->next->next = p;
}
private:
Node* head;
Node* tail;
unsigned int theSize;
void init()
{
head = new Node();
tail = new Node();
head->next = tail;
tail->next = 0;
theSize = 0;
}
};
#endif
//double.hpp
//中间加了判断迭代器的功能,应用时该用throw抛出异常来代替现在的cerr
//另,这个判断迭代器功能只用在了insert里,别的懒得写了
#ifndef DOUBLE_HPP__
#define DOUBLE_HPP__
#include <iostream>
#include <cassert>
template<typename Object>
class List {
private:
class Node {
public:
Node(const Object& d = Object(), Node* p = 0, Node* n = 0) : data(d), next(n), prev(p) {}
public:
Object data;
Node* next;
Node* prev;
};
public:
class Const_Iterator {
public:
Const_Iterator() : current(0){}
const Object& operator* () const { return retrieve(); }
Const_Iterator& operator++()
{
current = current->next;
return *this;
}
Const_Iterator& operator++(int)
{
Const_Iterator old = *this;
++(*this);
return old;
}
Const_Iterator& operator--()
{
current = current->prev;
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(const List<Object> &lst, Node* p) : theList(&lst), current(p) {}
void assertValid()
{
assert(theList != 0 || current != 0 || current != theList->head);
}
const List<Object> *theList;
friend class List<Object>;
};
class Iterator : public Const_Iterator {
public:
Iterator(){}
Object& operator*() { return retrieve(); }
Object& operator*() const { return retrieve(); }
Iterator& operator++()
{
current = current->next;
return *this;
}
Iterator& operator++(int)
{
Node old = *this;
++(*this);
return old;
}
Iterator& operator--()
{
current = current->prev;
return *this;
}
Iterator& operator--(int)
{
Node old = *this;
--(*this);
return old;
}
bool operator==(const Iterator& rhs) const
{
return current == rhs.current;
}
bool operator!=(const Iterator& rhs) const
{
return !(*this == rhs);
}
private:
Iterator(List<Object> &lst, Node *p) : Const_Iterator(lst, p) {}
friend class List<Object>;
};
public:
List()
{
init();
}
List(const List& rhs)
{
init();
*this = rhs;
}
~List()
{
Clear();
delete head;
delete tail;
}
List& operator=(const List& rhs)
{
if(rhs == *this)
return *this;
Clear();
for(Const_Iterator it = rhs.Begin(); it != rhs.End(); ++ it)
Push_Back(*it);
return *this;
}
Iterator Begin() { return Iterator(*this, head->next); }
Const_Iterator Begin() const { return Const_Iterator(*this, head->next); }
Iterator End() { return Iterator(*this, tail); }
Const_Iterator End() const { return Const_Iterator(*this, tail); }
unsigned int Size() const { return theSize; }
bool Empty() const { return theSize == 0; }
void Clear()
{
while(!Empty())
Pop_Front();
}
Object& Front() { return *Begin(); }
const Object& Front() const { return *Begin(); }
Object& Back() { return *(--End()); }
const Object& Back() const { return *(--End()); }
void Push_Front(const Object& ob)
{
Insert(Begin(), ob);
}
void Push_Back(const Object& ob)
{
Insert(End(), ob);
}
void Pop_Front() { Erase(Begin()); }
void Pop_Back() { Erase(--End()); }
Iterator Insert(Iterator it, const Object& ob)
{
it.assertValid();
if(it.theList != this)
std::cerr << "Not the same list/n";
else
{
Node* p = it.current;
++theSize;
return Iterator(*this, p->prev = p->prev->next = new Node(ob, p->prev, p));
}
}
Iterator Erase(Iterator it)
{
Node* p = it.current;
Iterator retVal(*this, p->next);
p->prev->next = p->next;
p->next->prev = p->prev;
delete p;
--theSize;
return retVal;
}
Iterator Erase(Iterator start, Iterator end)
{
for(Iterator it = start; it != end; )
it = Erase(it);
return end;
}
void swapAdj(Iterator it)
{
Node* first = it.current;
Node* second = (++it).current;
second->next->prev = first;
first->prev->next = second;
first->next = second->next;
second->prev = first->prev;
second->next = first;
first->prev = second;
}
private:
unsigned int theSize;
Node* head;
Node* tail;
void init()
{
theSize = 0;
head = new Node();
tail = new Node();
head->next = tail;
tail->prev = head;
}
};
#endif
//main.cpp
#include "single.hpp"
#include "double.hpp"
#include <iostream>
int main()
{
//SLList<int> l;
List<int> dl;
//l.push_front(2);
//l.push_front(1);
//l.push_front(3);
dl.Push_Back(3);
dl.Push_Back(2);
dl.Push_Back(1);
for(List<int>::Const_Iterator it = dl.Begin(); it != dl.End(); ++it)
std::cout << *it << std::endl;
List<int>::Iterator it = dl.Begin();
++it;
dl.swapAdj(it);
std::cout << "after swap: " << std::endl;
for(List<int>::Const_Iterator it = dl.Begin(); it != dl.End(); ++it)
std::cout << *it << std::endl;
std::cout << "/n";
for(List<int>::Const_Iterator it = --dl.End(); it != --dl.Begin(); --it)
std::cout << *it << std::endl;
return 0;
}