list实现

//为了不与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();
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值