实现不带头结点的单链表

链表:链表是一种线性表,但不是顺序存储,而是每个节点里面存储者下一个节点的指针,把存储数据元素的数据串链起来



不带头结点的链表也可以分为三种:


我们的代码实现的是第二种:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<assert.h>
using namespace std;

//不带头结点的链表(含有指向头结点和尾节点的指针)
template<class	T>
struct ListNode
{
	T _data;
	ListNode* _next;

	ListNode(const T& x)
		:_data(x)
		, _next(NULL)
	{}
};

template<class T>
class List
{
	typedef ListNode<T> Node;
public:
	List()
		:_head(NULL)
		, _tail(NULL)
	{}

	List(const List& s)
		:_head(NULL)
		, _tail(NULL)
	{
		Node* cur = s._head;
		while (cur)
		{
			if (_head == NULL)
			{
				_head = _tail = new Node(cur->_data);
			}
			else
			{
				_tail->_next = new Node(cur->_data);
				cur = cur->_next;
			}
			cur = cur->_next;
		}
	}

	~List()
	{
		Node* cur = _head;
		while (cur)
		{
			Node* tmp = cur;
			cur = cur->_next;
			delete tmp;
		}
		_head = _tail = NULL;
	}

	void PushBack(const T& x) //尾插
	{
		if (_head == NULL)
		{
			_head = _tail = new Node(x);
		}
		else
		{
			_tail->_next = new Node(x);
			_tail = _tail->_next;
		}
	}

	void PopBack() //尾删
	{
		if (_head == NULL)
		{
			return;
		}
		else if (_head->_next==NULL)
		{
			delete _head;
			_head = _tail = NULL;
		}
		else
		{
			Node* prev=_head;
			while (prev->_next != _tail)
			{
				prev = prev->_next;
			}
			_tail = NULL;
			_tail = prev;
			_tail->_next = NULL;
		}
	}

	void PushFront(const T& x)//头插
	{
		if (_head == NULL)
		{
			_head = _tail = new Node(x);
		}
		else
		{
			Node* tmp = new Node(x);
			tmp->_next = _head;
			_head = tmp;
		}
	}

	void PopFront()//头删
	{
		if (_head == NULL)
		{
			return;
		}
		else if (_head->_next == NULL)
		{
			delete _head;
			_head = _tail = NULL;
		}
		else
		{
			Node* cur = _head->_next;
			delete _head;
			_head = cur;
		}
	}

	Node* Find(const T& x)
	{
		Node* cur = _head;
		while (cur)
		{
			if (cur->_data == x)
			{
				return cur;
			}
			cur = cur->_next;
		}
		return (Node*) -1;
	}

	void Insert(Node* pos, const T& x)//pos后面插入
	{
		assert(pos);
		Node* tmp = new Node(x);
		Node* cur = _head;
		Node* prev = cur;
		while (cur != pos)
		{
			cur=cur->_next;
			prev = cur;
		}
		tmp->_next = cur->_next;
		prev->_next = tmp;
		
	}

	void Print()// 打印链表
	{
		Node* cur = _head;
		while (cur)
		{
			cout << cur->_data << " ";
			cur = cur->_next;
		}
		cout << endl;
	}

	void Erase(Node* pos)// 删除
	{
		assert(pos);
		if (_head == pos)
		{
			PopFront();
		}
		else if (_tail == pos)
		{
			PopBack();
		}
		else
		{
			Node* cur = _head;
			Node* prev = _head;
			while (cur != pos)
			{
				prev = cur;
				cur=cur->_next;
			}
			prev->_next = cur->_next;
		}
	}


	void Reverse()                   //逆置  
	{
		assert(_head);
		Node *cur = _head;
		Node *NewHead = NULL;
		while (cur)
		{
			Node* tmp = cur;tmp->_next = NewHead;
			NewHead = tmp;
			if (NewHead == _head)
			{
				_tail = NewHead;
			}
		}
		_head = NewHead;
	}
	

private:
	Node* _head;
	Node* _tail;
};

void Test()
{
	List<int> t;
	t.PushBack(1);
	t.PushBack(2);
	t.PushBack(3);
	t.PushBack(4);
	t.Print();

	/*t.PopBack();
	t.Print();*/
	/*t.PushFront(0);
	t.Print();

	t.PopFront();
	t.Print();*/
	/*t.Insert(t.Find(1), 0);
	t.Print();
	t.Erase(t.Find(0));
	t.Print();*/
	t.Reverse();
	t.Print();
}
int main()
{
	Test();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值