看了《C++沉思录》第15章,手动写了下代码,加深点印象
#ifndef __SEQ__H_
#define __SEQ__H_
#include "Seq_item.h"
#include <iostream>
using namespace std;
template<class T>
class Seq_item;
template<class T>
class Seq
{
public:
Seq();
Seq(const T&, const Seq&);
Seq(const Seq&);
Seq(Seq_item<T>* s);
~Seq();
T hd() const;
Seq tl() const;
void destory(Seq_item<T>* item);
operator bool() const;
Seq& operator=(const Seq&);
Seq<T>& operator==(const Seq<T>& s);
Seq<T>& operator++();
Seq<T> operator++(int);
T operator*();
int length(Seq<T> s);
Seq<T>& insert(const T& t);
Seq<T> cons(const T& t, const Seq<T>& s);
Seq<T> merge(const Seq<T>& x, const Seq<T>& y);
void split(Seq<T> x, Seq<T>& y, Seq<T>& z);
Seq<T> sort(const Seq<T>& x);
Seq_item<T>* owntail();
Seq<T>& flip();
private:
Seq_item<T>* item;
};
template<class T>
Seq<T>::Seq():item(0)
{
cout << "Seq<T>::Seq" << endl;
}
template<class T>
Seq<T>::Seq(const T& t, const Seq<T>& x):
item(new Seq_item<T>(t, x.item)) {}
template<class T>
Seq<T>::operator bool() const
{
return item != 0;
}
template<class T>
Seq<T>::Seq(const Seq<T>& s):item(s.item)
{
if (item)
{
item->use++;
}
}
template<class T>
T Seq<T>::hd() const
{
if (item)
{
return item->data;
}
else
{
throw "hd of an emtpy Seq";
}
}
template<class T>
Seq<T>::Seq(Seq_item<T>* s): item(s)
{
if (s)
{
s->use++;
}
}
template<class T>
Seq<T> Seq<T>::tl() const
{
if (item)
{
return Seq<T>(item->next);
}
else
{
throw "tl of an empty Seq";
}
}
template<class T>
Seq<T>& Seq<T>::operator==(const Seq<T>& s)
{
if (s.item)
{
s.item->use++;
}
destroy(item);
item = s.item;
return *this;
}
template<class T>
Seq<T>::~Seq()
{
destory(item);
}
template<class T>
void Seq<T>::destory(Seq_item<T>* item)
{
while(item && --item->use == 0)
{
Seq_item<T>* next = item->next;
delete item;
item = next;
}
}
template<class T>
int Seq<T>::length(Seq<T> s)
{
int n = 0;
while(s)
{
s = s.tl();
n++;
}
return n;
}
template<class T>
T Seq<T>::operator*()
{
return hd();
}
template<class T>
Seq<T> Seq<T>::cons(const T& t, const Seq<T>& s)
{
return Seq<T>(t, s);
}
template<class T>
Seq<T>& Seq<T>::insert(const T& t)
{
item = new Seq_item<T>(t, item);
return *this;
}
template<class T>
Seq<T> Seq<T>::operator++(int)
{
Seq<T> ret = *this;
if (item)
{
--item->use;
item = item->next;
if (item)
{
item->use++;
}
}
return ret;
}
template<class T>
Seq<T>& Seq<T>::operator++()
{
if (item)
{
Seq_item<T>* p = item->next;
if (p)
{
p->use++;
}
if (--item->use == 0)
{
delete item;
}
item = p;
}
return *this;
}
template<class T>
void Seq<T>::split(Seq<T> x, Seq<T>& y, Seq<T>& z)
{
while (x)
{
y.insert(x.hd());
if (++x)
{
z.insert(x.hd());
++x;
}
}
}
template<class T>
Seq_item<T>* Seq<T>::owntail()
{
if (item == 0)
{
return 0;
}
Seq_item<T>* i = item;
Seq_item<T>** p = &item;
while(i->use == 1)
{
if (i->next == 0)
{
return i;
}
p = &i->next;
i = i->next;
}
*p = new Seq_item<T>(i->data);
--i->use;
i = i->next;
Seq_item<T>* j = *p;
while(i)
{
j->next = new Seq_item<T>(i->data);
i = i->next;
j = j->next;
}
return j;
}
template<class T>
Seq<T>& Seq<T>::flip()
{
if (item)
{
Seq_item<T>* k = owntail();
Seq_item<T>* curr = item;
Seq_item<T>* behind = 0;
do
{
Seq_item<T>* ahead = curr->next;
curr->next = behind;
behind = curr;
curr = ahead;
}while(curr);
item = k;
}
return *this;
}
template<class T>
Seq<T> Seq<T>::sort(const Seq<T>& x)
{
if (!x || !x.tl()) return x;
Seq<T> p, q;
split(x, p, q);
return merge(sort(p), sort(q));
}
template<class T>
Seq<T> Seq<T>::merge(const Seq<T>& x, const Seq<T>& y)
{
if (!x) return y;
if (!y) return x;
T xh = x.hd();
T yh = y.hd();
if (xh < yh)
{
return cons(xh, merge(x.tl(), y));
}
return cons(yh, merge(x, y.tl()));
}
#endif ///__SEQ_H_
#ifndef __SEQ_ITEM__H_
#define __SEQ_ITEM__H_
#include "Seq.h"
template<class T>
class Seq;
template<class T>
class Seq_item
{
friend class Seq<T>;
int use;
const T data;
Seq_item* next;
Seq_item(const T& t, Seq_item* s);
Seq_item(const T& t): use(1), data(t), next(0){}
};
///当我开始敲这这个构造函数的时候,我才知道为什么是s->use++,看书的时候不懂为什么是s->use++
template<class T>
Seq_item<T>::Seq_item(const T& t, Seq_item<T>* s):
use(1), data(t), next(s)
{
if (s)
{
s->use++;
}
}
#endif ///__SEQ_ITEM_H_