您的位置:首页 > 编程语言 > C语言/C++

c++stl库list简单的实现

2012-03-31 19:05 260 查看
//stl库中的list其实就是一个双向链表,还构造了一个iterator,去遍历list。

//所以,实现list的关键其实就是2点:

//1、构造一个 listNode,这个就是我们链表的节点。

//2、构造一个iterator,这个是我们遍历这个链表的工具。

//其他的一些操作,其实就是链表的一些基本操作而已。

//我选择的是一种双向,不循环链表。

//用first,last这2个,指针分别指向链表的头尾。count记录链表的元素

//直接看代码吧;

//对stl库中 iterator只能++,--做了改进,支持iterator+num,这里不能超出范围,具体没有仔细测试。

//不够好地方,还请大家指正。

#ifndef _MY_LIST_H_
#define _MY_LIST_H_

template<typename T>
class myList
{
private:
//list node
//double link
struct ListNode
{
ListNode()
{

}

ListNode(const T& e):element(e),next(0),prev(0)
{

}

T element;
ListNode* next;
ListNode* prev;
};
public:
//iterator
class Iterator
{
public:
//default constructor;
Iterator():current(0)
{

}

//ListNode* constructor;
Iterator(ListNode* node):current(node)
{

}

//copy constructor;
Iterator(const Iterator& iter):current(iter.current)
{

}

//= constructor
Iterator& operator =(const Iterator& other)
{
current = other.current;
return *this;
}

//++iterator;
Iterator& operator ++()
{
current = current->next;
return *this;
}

//--iterator;
Iterator& operator --()
{
current = current->prev;
return *this;
}

//iterator++;
Iterator operator ++(int)
{
Iterator tmp = *this;
current = current->next;
return tmp;
}

//iterator--;
Iterator operator --(int)
{
Iterator tmp = *this;
current = current->prev;
return tmp;
}

//iterator += num;
//return an iterator;
//if num+iterator pos>myList.size();
//return the end iterator;
Iterator& operator +=(int num)
{
if(num > 0)
{
while (num-- && this->current != 0) ++(*this);
}
else
{
while(num++ && this->current != 0) --(*this);
}
return *this;
}

//iterator + num;
Iterator operator +(int num)
{
Iterator tmp = *this;
return tmp += num;
}

//iterator -= num;
Iterator& operator -=(int num)
{
return (*this)+=(-num);
}

//iterator - num;
Iterator operator -(int num)
{
return (*this)+(-num);
}

//iterator1 == iterator2;
bool operator ==(const Iterator& other)
{
return current == other.current;
}

//iterator1 != iterator2;
bool operator !=(const Iterator& other)
{
return current != other.current;
}

//(*iterator)
T& operator *()
{
return current->element;
}

//iterator->
T* operator ->()
{
return ¤t->element;
}

ListNode* current;
};

public:
//default constructor
myList():first(0),last(0),count(0)
{

}

//copy constructor
myList(myList<T>& other):first(0),last(0),count(0)
{
*this = other;
}

//= constructor
myList<T>& operator =(myList<T>& other)
{
if(&other == this)
return *this;

clear();
Iterator it = other.begin();
for(;it != other.end();++it)
{
push_back(*it);
}
return *this;
}

//destructor
~myList()
{
clear();
}

//clear myList
void clear()
{
while(first)
{
ListNode* next = first->next;
deallocate(first);
first = next;
}

last = 0;
count = 0;
}

//return the size of myList
unsigned int size()
{
return count;
}

//is empty
bool empty()
{
return count == 0;
}

//adds an element at the begin of myList
void push_front(const T& t)
{
ListNode* node = allocator(t);
++count;

if (first == 0)
{
last = node;
first = node;
}
else
{
node->next = first;
first->prev = node;
first = node;
}
}

//adds an element at the end of the list.
void push_back(const T& t)
{
ListNode* node = allocator(t);
++count;

if (first == 0)
first = node;

node->prev = last;

if (last != 0)
last->next = node;

last = node;
}

//inserts an element before an element.
//param it Iterator pointing to element before which the new element should be inserted.
//param element The new element to be inserted into the list.
void insert_after(const Iterator& it, const T& t)
{
ListNode* node = allocator(t);
++count;

node->next = it.current->next;

if (it.current->next)
it.current->next->prev = node;

node->prev = it.current;
it.current->next = node;

if (it.current == last)
last = node;
}

//inserts an element before an element.
//param it Iterator pointing to element before which the new element should be inserted.
//param element The new element to be inserted into the list.
void insert_before(const Iterator& it,const T& t)
{
ListNode* node = allocator(t);
++count;

node->prev = it.current->prev;

if (it.current->prev)
it.current->prev->next = node;

node->next = it.current;
it.current->prev = node;

if (it.current == first)
first = node;
}

//erases an element.
//param it Iterator pointing to the element which shall be erased.
//return Iterator pointing to next element.
//warning: if an iterator is erased, the iterator must be assigned again
//super: Iterator it = begin();it = earse(it);
Iterator erase(Iterator& it)
{
Iterator returnIterator(it);
++returnIterator;

if(it.current == first)
{
first = it.current->next;
}
else
{
it.current->prev->next = it.current->next;
}

if(it.current == last)
{
last = it.current->prev;
}
else
{
it.current->next->prev = it.current->prev;
}

deallocate(it.current);
it.current = 0;
--count;

return returnIterator;
}

//gets first node.
//return A list iterator pointing to the beginning of the list.
Iterator begin()
{
return Iterator(first);
}

//gets end node.
//return List iterator pointing to null.
Iterator end()
{
return Iterator(0);
}

private:
ListNode* allocator(const T& t)
{
return new ListNode(t);
}

void deallocate(ListNode* node)
{
if(node)
delete node;
}

private:
ListNode*		first;
ListNode*		last;
unsigned int	count;
};

#endif


//下面的测试代码

void printfList(myList<int>& list)
{
myList<int>::Iterator it;
for(it = list.begin();it != list.end();++it)
{
cout<<*it<<",";
}
cout<<" size = "<<list.size()<<endl;
}

void main()
{
myList<int> mylist1;
myList<int>::Iterator it;
mylist1.push_back(2);
mylist1.push_front(1);

it = mylist1.begin();
mylist1.insert_after(it,0);
cout<<*it<<endl;

mylist1.insert_before(it,-1);
cout<<*it<<endl;

printfList(mylist1);
it = mylist1.erase(it);
cout<<*it<<endl;

printfList(mylist1);

cout<<*(it-1)<<endl;

myList<int> mylist2(mylist1);
printfList(mylist2);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: