图示
代码
#include<iostream>
using namespace std;
template<class T> class LoopList;
template<class T> class LoopList_iter;
template<class T>
class Node
{
friend class LoopList<T>;
friend class LoopList_iter<T>;
public:
private:
Node(const T& item = T())
:data(item), next(nullptr) { };
T data;
Node<T>* next;
};
template<class T>
class LoopList
{
friend class LoopList_iter<T>;
public:
LoopList()
: head(new Node<T>) { tailNode = head->next = head; };
~LoopList();
void Insert(const T& item);
void Delete(const T& item);
bool IsEmpty() const;
void Show() const;
private:
Node<T>* head;
Node<T>* tailNode;
};
template<class T>
LoopList<T>::~LoopList()
{
while (!IsEmpty()) {
Node<T>* del = head->next;
head->next = del->next;
del->data.~T();
delete del;
}
delete head;
}
template<class T>
void LoopList<T>::Insert(const T& item)
{
Node<T>* crtNode = new Node<T>(item);
if (IsEmpty()) {
crtNode->next = head->next;
head->next = crtNode;
} else {
crtNode->next = tailNode->next;
tailNode->next = crtNode;
}
tailNode = crtNode;
}
template<class T>
void LoopList<T>::Delete(const T& item)
{
Node<T>* crtNode = head->next;
Node<T>* prevNode = head;
while (crtNode != head && crtNode->data != item) {
prevNode = crtNode;
crtNode = crtNode->next;
}
if (crtNode != head) {
if (crtNode == tailNode)
tailNode = prevNode;
prevNode->next = crtNode->next;
crtNode->data.~T();
delete crtNode;
}
}
template<class T>
bool LoopList<T>::IsEmpty() const
{
return (head == head->next);
}
template<class T>
void LoopList<T>::Show() const
{
Node<T>* p = head->next;
while (p != head) {
cout << p->data;
p = p->next;
if (p != head)
cout << " -> ";
}
cout << endl;
}
template<class T>
class LoopList_iter
{
typedef LoopList_iter self;
public:
LoopList_iter(const LoopList<T>& l)
: llist(l), node(llist.head->next) { }
T& operator* ()
{
if (llist.IsEmpty()) {
cerr << "\nabort(), loop list is empty.\n";
abort();
}
return node->data;
}
self operator++ (int)
{
self prev(llist);
prev.node = node;
if (!llist.IsEmpty() && node->next == llist.head) {
node = node->next->next;
} else {
node = node->next;
}
return prev;
}
self& operator++ ()
{
if (!llist.IsEmpty() && node->next == llist.head) {
node = node->next->next;
} else {
node = node->next;
}
return *this;
}
private:
const LoopList<T>& llist;
Node<T>* node;
};
int main()
{
#define NUMS (4)
LoopList<int> LList;
cout << "first insert ";
for (int i=0; i<NUMS; ++i) LList.Insert(i); LList.Show();
cout << "delete part ";
for (int i=0; i<NUMS; i+=2) LList.Delete(i); LList.Show();
cout << "delete again ";
for (int i=1; i<NUMS; i+=2) LList.Delete(i); LList.Show();
cout << "insert again ";
for (int i=0; i<2*NUMS; ++i) LList.Insert(i); LList.Show();
cout << "delete again ";
for (int i=0; i<2*NUMS; i+=2) LList.Delete(i); LList.Show();
cout << "iterator++ ";
LoopList_iter<int> it(LList);
for (int i=0; i<10; ++i) {
cout << *it << " ";
it++;
}
cout << "\n++iterator ";
LoopList_iter<int> it1(LList);
for (int i=0; i<10; ++i) {
cout << *it1 << " ";
++it1;
}
LList.~LoopList();
cout << "\n======== over =========" << endl;
return 0;
}
Makefile
CC = g++
DIR_BUILD = build
SRCS = loop_list.cpp
INCS = ./
TARGET = ./main.exe
OBJS = $(patsubst %.cpp, $(DIR_BUILD)/%.o, $(notdir $(SRCS)))
FLAGS = -std=gnu++11
all: $(DIR_BUILD) $(TARGET)
@echo -e ---- Compilation completed, the TARGET in "'$(TARGET)' ---- \n"
$(TARGET): $(OBJS)
$(CC) $(FLAGS) -o $@ $^
$(OBJS): $(SRCS)
$(CC) $(FLAGS) -I$(INCS) -c $^ -o $@
$(DIR_BUILD):
if [ ! -d $(DIR_BUILD) ]; then mkdir -p $(DIR_BUILD); fi
clean:
rm -rf $(DIR_BUILD)
rm -rf $(OBJS) $(TARGET)