简单列表的实现(基于双向链表)

实现一个简单的列表,基于双向链表,要求支持删除,插入,下标等操作。


#ifndef _DOUBLELINKEDLIST_
#define  _DOUBLELINKEDLIST_

#include <iostream>
#include <stdexcept>
using namespace std;

template <typename T>
class DoubleLinkedList
{
private:
	struct DoubleLinkedListNode
	{
		T data;
		DoubleLinkedListNode* previous;
		DoubleLinkedListNode* next;
		DoubleLinkedListNode(const T& v,DoubleLinkedListNode* p = NULL,DoubleLinkedListNode* n= NULL) : data(v), previous(p),next(n) {}
	};

public:
	DoubleLinkedList() : size(0),currentIndex(-1),current(NULL) {}
	~DoubleLinkedList() { Clear(); }
	DoubleLinkedList(const DoubleLinkedList& rhs) : size(0),currentIndex(-1),current(NULL)
	{
		operator=(rhs);
	}

	const DoubleLinkedList& operator= ( const DoubleLinkedList& rhs )
	{
		if( this != &rhs )
		{
			Clear();
			if(!rhs.IsEmpty())
			{
				int oldCurrentIndex = rhs.currentIndex;

				rhs.SetCurrentIndex(0);
				DoubleLinkedListNode* temp = rhs.current;
				while(temp != NULL)
				{
					Add(temp->data);
					temp = temp->next;
				}

				rhs.SetCurrentIndex(oldCurrentIndex);
				this->SetCurrentIndex(oldCurrentIndex);
			}
		}

		return *this;
	}

	int Size() const { return size; }
	bool IsEmpty() const { return size == 0; }
	void Clear()
	{
		if(!IsEmpty())
		{
			SetCurrentIndex(0);
			DoubleLinkedListNode* temp = current;
			while(temp != NULL)
			{
				current = current->next;
				delete temp;
				temp = current;
			}

			size = 0;
			currentIndex = -1;
			current = NULL;
		}
	}

	void Print()
	{
		cout << "Size=" << size << endl;
		cout << "CurrentIndex=" << currentIndex << endl;
		cout << "Current=" << current;
		cout << endl;

		if(!IsEmpty())
		{
			SetCurrentIndex(0);
			DoubleLinkedListNode* temp = current;
			while(temp != NULL)
			{
				cout << temp->data << ",";
				temp = temp->next;
			}
			cout << endl;
		}
	}

	void Insert(int index,const T& value)
	{
		if( index < 0 || index > size )
			throw logic_error("Index is not valid for insertion");

		if(IsEmpty())
		{
			current = new DoubleLinkedListNode(value,NULL,NULL);
			currentIndex = 0;
			++size;
			return;
		}
		else if(index == size)
		{
			SetCurrentIndex(index-1);
			current->next = new DoubleLinkedListNode(value,current,current->next);
			++currentIndex;
			current=current->next;
			++size;
			return;
		}
		else
		{
			SetCurrentIndex(index);
			DoubleLinkedListNode* temp = new DoubleLinkedListNode(value,current->previous,current);
			current->previous = temp;
			if(temp->previous != NULL)
				temp->previous->next = temp;
			current = temp;
			++size;
			return;
		}
	}

	void Add(const T& value)
	{
		Insert(size, value);
	}

	T Remove(int index)
	{
		if(IsEmpty())
			throw logic_error("List is empty");

		CheckRange(index);

		SetCurrentIndex(index);

		T value;
		DoubleLinkedListNode* temp = current;
		value = temp->data;

		if(size == 1)
		{
			current = NULL;
			currentIndex = -1;
		}
		else
		{
			if(index == 0)
			{
				current->next->previous = current->previous;
				current = current->next;
			}
			else if(index == size -1 )
			{
				current->previous->next = current->next;
				current = current->previous;
				--currentIndex;
			}
			else
			{
				current->previous->next = current->next;
				current->next->previous = current->previous;
				current = current->next;
			}
		}

		delete temp;
		--size;
		return value;
	}

	T Remove()
	{
		return Remove(size-1);
	}

	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(currentIndex == index)
			return;
		else if(currentIndex < index)
		{
			for( ; currentIndex < index; ++currentIndex)
				current = current->next;
		}
		else
		{
			for( ; currentIndex > index; --currentIndex)
				current = current->previous;
		}
	}

	void CheckRange(int index) const
	{
		if( index < 0 || index >= size)
			throw logic_error("Invalid index value");
	}

	int size;

	mutable int currentIndex;
	mutable DoubleLinkedListNode* current;
};
#endif


测试代码:

#include "DoubleLinkedList.cpp"

void DoubleLinkedListTest1();
void Test( void (*fp)() );

int main(int argc, char** argv)
{
	Test(DoubleLinkedListTest1);
	return 0;
}

void DoubleLinkedListTest1()
{
	DoubleLinkedList<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;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值