//为了不与stl冲突,使用命名空间
namespace Swy
{
//类型用模板,因此实现都在头文件中
//swy实现链表
template<class elemType>
class list_item
{
public:
list_item(elemType value, list_item* link = 0)
:_value(value)
{
//把value插入到link的后面
if (link == NULL)
_next = 0;
else
{
_next = link->_next;
link->_next = this;
}
}
~list_item() {}
elemType value() { return _value; }
list_item* next() { return _next; }
void next(list_item* ptr) { _next = ptr; }
private:
elemType _value;
list_item* _next;
};
template<class elemType>
class list {
public:
list()
:_at_front(0),
_at_end(0),
_size(0)
{
}
~list()
{
}
inline int size() { return _size; }
//提供头指针访问接口,这样 其他模块可以访问头,然后listitem可以访问next(),这样就可以遍历list了
list_item<elemType>* front() { return _at_front; }
//但是这样还是不完美, 类似STL中迭代器模式的最好
void insert(list_item<elemType>* ptr, elemType value)
{
//在ptr后面插入value
if (ptr == NULL)
{
//插入头
insert_front(value);
}
else
{
bump_up_size();
list_item<elemType>* item = new list_item<elemType>(value, ptr);
}
}
void insert_front(elemType value)
{
list_item<elemType>* ptr = new list_item<elemType>(value);
if (_at_front == NULL)
{
_at_front = ptr;
_at_end = ptr;
}
else
{
//头部之前插入value,那么ptr变成头部,ptr的next指向原来的头部
ptr->next(_at_front);
_at_front = ptr;
}
bump_up_size();
}
void insert_end(elemType value)
{
if (_at_end == NULL)
{
list_item<elemType>* ptr = new list_item<elemType>(value);
_at_front = ptr;
_at_end = ptr;
}
else
{
//尾部之后插入value
list_item<elemType>* ptr = new list_item<elemType>(value, _at_end);
_at_end = ptr;
}
bump_up_size();
}
list_item<elemType>* find(elemType value)
{
list_item<elemType>* ptr = _at_front;
while (ptr)
{
if (ptr->value() == value)
break;
ptr = ptr->next();
}
return ptr;
}
void display(std::ostream& os = std::cout)
{
os << "\n(" << _size << ")(";
//遍历 注意是 next 不是iter++
list_item<elemType>* ptr = _at_front;
while (ptr)
{
os << ptr->value() << " ";
ptr = ptr->next();
}
os << ")\n";
}
void remove_front()
{
if (_at_front)
{
list_item<elemType>* ptr = _at_front;
_at_front = _at_front->next();
bump_down_size();
delete ptr;
}
}
void remove_all()
{
while (_at_front)
{
remove_front();
}
_size = 0;
_at_front = 0;
_at_end = 0;
}
int remove(elemType value)
{
list_item<elemType>* ptr = _at_front;
list_item<elemType>* prev = _at_front;
int elem_cnt = 0;
while (ptr)
{
if (ptr->value() - value < 0.0001)
{
++elem_cnt;
if (ptr == _at_front)
{
//删了头部
remove_front();
ptr = _at_front;
prev = _at_front;
}
else
{
prev->next(ptr->next());
bump_down_size();
delete ptr;
ptr = prev->next();
if (ptr == NULL)
{
//删了尾节点 因此需要重新赋值尾节点
_at_end = prev;
return elem_cnt;
}
}
}
else
{
prev = ptr;
ptr = ptr->next();
}
}
if (_size == 0)
{
_size = 0;
_at_front = 0;
_at_end = 0;
}
return elem_cnt;
}
void concat(const list& il)
{
//连接
//_at_end->next(il._at_front); xxxx
//注意不能 指针直接连起来,后面改变母链表 子链表的内容也变了 所以需要 深拷贝
list_item<elemType>* ptr = il._at_front;
while (ptr)
{
insert_end(ptr->value());//insert_end new了一个 问题解决
ptr = ptr->next();
}
}
void reverse()
{
//翻转
if (_size <= 0)
return;
list_item<elemType>* prev = NULL;
list_item<elemType>* ptr = _at_front;
_at_front = _at_end;
_at_end = ptr;
while (ptr != _at_front)
{
list_item<elemType>* tmp = ptr->next();
ptr->next(prev);
prev = ptr;
ptr = tmp;
}
_at_front->next(prev);
}
//长度的增加使用统一的接口而不是单独的增加减少
inline void bump_up_size() { ++_size; }
inline void bump_down_size() { --_size; }
//private:
//禁止拷贝和赋值
//拷贝构造操作
list(const list& li)
{
remove_all();
concat(li);
}
//拷贝赋值操作
list& operator=(const list& li)
{
if (this != &li)
{
remove_all();
concat(li);
}
return *this;
}
private:
list_item<elemType>* _at_front;
list_item<elemType>* _at_end;
int _size;
};
}
下面是使用
int main()
{
Swy::list<int> mylist;
for (int i = 0; i < 10; i++)
{
mylist.insert_front(i);
//mylist.insert_end(i);
}
std::cout << "OK: after insert_front and insert_end()\n";
mylist.display();
Swy::list_item<int>* it = mylist.find(8);
mylist.insert(it, 120);
mylist.display();
std::cout << "\n insert 120 after 8\n";
int elem_cnt = mylist.remove(2);
std::cout << "\n removed" << elem_cnt << "of the value 2\n";
mylist.display();
mylist.reverse();
std::cout << "\n after reverse \n";
mylist.display();
//mylist.remove_all();
//std::cout << "\n remove all\n";
//mylist.display();
for (int i = 0; i < 5; i++)
{
mylist.insert_front(2);
}
mylist.display();
elem_cnt = mylist.remove(2);
std::cout << "\n removed" << elem_cnt << "of the value 2\n";
mylist.display();
for (int i = 0; i < 5; i++)
{
mylist.insert_end(3);
}
mylist.display();
elem_cnt = mylist.remove(3);
std::cout << "\n removed" << elem_cnt << "of the value 3\n";
mylist.display();
Swy::list<int> yourlist;
yourlist = mylist;
//yourlist(mylist);
for (int i = 0; i < 3; i++)
{
yourlist.insert_end(i);
//mylist.insert_end(i);
}
yourlist.concat(mylist);
yourlist.display();
std::cout << "\n concat \n";
yourlist.reverse();
std::cout << "\n after reverse \n";
yourlist.display();
}