实现一个列表,基于链表,支持插入,删除,下标等操作。
#ifndef _LINKEDLIST_
#define _LINKEDLIST_
#include <iostream>
#include <stdexcept>
using namespace std;
template <typename T>
class LinkedList
{
private:
struct LinkedListNode
{
T data;
LinkedListNode* next;
LinkedListNode(const T& v,LinkedListNode* n = NULL) : data(v),next(n) {}
};
public:
LinkedList() : _size(0),_currentIndex(-1),_current(NULL),_head(NULL) {}
~LinkedList() {}
LinkedList( const LinkedList& rhs ) : _size(0),_currentIndex(-1),_current(NULL),_head(NULL)
{
operator=(rhs);
}
const LinkedList& operator= ( const LinkedList& rhs)
{
if( this != &rhs )
{
Clear();
if(!rhs.IsEmpty())
{
LinkedListNode* temp = rhs._head;
while(temp != NULL)
{
Add(temp->data);
temp = temp->next;
}
_currentIndex = 0;
_current = _head;
for( ;_currentIndex < rhs._currentIndex; ++_currentIndex )
{
_current = _current->next;
}
}
}
return *this;
}
void Insert(int index,const T& value);
void Add(const T& value);
T Remove();
T Remove(int index);
void Clear()
{
_size = 0;
_currentIndex = -1;
_current = NULL;
LinkedListNode* temp = _head;
while(temp != NULL)
{
_head = _head->next;
delete temp;
temp = _head;
}
_head = NULL;
}
void Print() const
{
cout << "Size=" << _size << endl;
cout << "CurrentIndex=" << _currentIndex << endl;
cout << "Current=" << _current;
cout << endl;
LinkedListNode* temp = _head;
while(temp != NULL)
{
cout << temp->data << ",";
temp = temp->next;
}
cout << endl;
}
int Size() const { return _size; }
bool IsEmpty() const {return _size == 0; }
T& operator[](int index)
{
return ElementAt(index);
}
const T& operator[](int index) const
{
return ElementAt(index);
}
private:
T& ElementAt(int index) const
{
if(IsEmpty())
throw logic_error("List is empty");
SetCurrentIndex(index);
return _current->data;
}
void SetCurrentIndex(int index) const
{
CheckRange(index);
if(index < _currentIndex )
{
_currentIndex = 0;
_current = _head;
}
for( ; _currentIndex < index; ++ _currentIndex )
_current = _current->next;
}
void CheckRange(int index) const
{
if(index < 0 || index >= _size)
throw logic_error("Invalid index");
}
int _size;
mutable int _currentIndex;
mutable LinkedListNode* _current;
LinkedListNode* _head;
};
template <typename T>
void LinkedList<T>::Add(const T& value)
{
if( _size == 0 )
{
_head = new LinkedListNode(value,NULL);
_currentIndex = 0;
_current = _head;
}
else
{
SetCurrentIndex(_size-1);
_current->next = new LinkedListNode(value,NULL);
_current = _current->next;
++_currentIndex;
}
++_size;
}
template <typename T>
void LinkedList<T>::Insert(int index,const T& value)
{
if( index < 0 || index > _size)
throw logic_error("Invalid index for insertion operation");
if(index == 0)
{
_head = new LinkedListNode(value,_head);
_currentIndex = 0;
_current = _head;
}
else
{
SetCurrentIndex(index - 1);
_current->next = new LinkedListNode(value,_current->next);
_current = _current->next;
++_currentIndex;
}
++_size;
}
template <typename T>
T LinkedList<T>::Remove()
{
if(IsEmpty())
throw logic_error("List is empty");
T value;
if(_size == 1)
{
value = _head->data;
delete _head;
_head = _current = NULL;
_currentIndex = -1;
}
else
{
SetCurrentIndex(_size - 2);
value = _current->next->data;
delete _current->next;
_current->next = NULL;
}
--_size;
return value;
}
template <typename T>
T LinkedList<T>::Remove(int index)
{
if(IsEmpty())
throw logic_error("List is empty");
CheckRange(index);
T value;
if(index == 0)
{
LinkedListNode* temp = _head;
value = temp->data;
_head = _current = temp->next;
if(_size == 1)
_currentIndex = -1;
else
_currentIndex = 0;
}
else
{
SetCurrentIndex(index-1);
LinkedListNode* temp = _current->next;
_current->next = temp->next;
value = temp->data;
delete temp;
}
--_size;
return value;
}
#endif
测试代码:
#include "LinkedList.cpp"
void LinkedListTest1();
void Test( void (*fp)() );
int main(int argc, char** argv)
{
Test(LinkedListTest1);
return 0;
}
void LinkedListTest1()
{
LinkedList<int> v;
int removed = 0 ;
v.Print();
v.Add(5);
v.Add(8);
v.Add(10);
v.Print();
v.Insert(3,20);
v.Print();
v.Insert(1,22);
v.Print();
v.Insert(0,28);
v.Print();
v.Add(101);
v.Add(102);
v.Add(103);
v.Add(104);
v.Print();
removed = v.Remove();
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(105);
v.Print();
removed = v.Remove(0);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(106);
removed = v.Remove(v.Size()-1);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(107);
removed = v.Remove(5);
v.Print();
cout<< "Removed=" << removed << endl;
v.Add(109);
v.Add(110);
v.Print();
for(int i=9;i>0;--i)
v.Insert(11,110+i);
v.Print();
v.Insert(11,150);
v.Print();
for(int i=0;i<v.Size();++i)
cout << v[i] << ",";
cout<<endl;
v.Remove(30);
}
void Test( void (*fp)() )
{
try
{
fp();
}
catch(out_of_range e)
{
cout<< "Catch Exception:" << e.what() << endl;
}
catch(overflow_error e)
{
cout<< "Catch Exception:" << e.what() << endl;
}
catch(logic_error e)
{
cout<< "Catch Exception:" << e.what() << endl;
}
}