码迷,mamicode.com
首页 > 编程语言 > 详细

C++实现单链表

时间:2016-03-20 02:20:11      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:c++      单链表   

单链表的结构有多种

这里介绍的链表有头结点、有尾节点并且尾节点指向头结点

技术分享

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

typedef int DataType;

struct LinkNode
{
	friend class SList;      //将SList设为友元,便于SList类可以访问节点类的私有成员
public:
	LinkNode(const DataType x)
		:_data(x)
		, _next(NULL)
	{}
private:
	DataType _data;    //节点的数据
	LinkNode* _next;    //指向该节点的下一个节点
};

class SList
{
public:
	SList()         //构造函数
		:_head(NULL)
		, _tail(NULL)
	{}
	SList(const SList& s)          //拷贝构造
		:_head(NULL)
		, _tail(NULL)
	{
		LinkNode* tmp = s._head;
		do{
			PushBack(tmp->_data);
			tmp = tmp->_next;
		    } while (tmp != s._head);
		
	}
	SList &operator=(const SList& s)    //赋值运算符的重载
	{
		if (this != &s)
		{
			_head = NULL;
			_tail = NULL;

			LinkNode* tmp = s._head;
		do{
			PushBack(tmp->_data);
			tmp = tmp->_next;
		     } while (tmp != s._head);
		}
		
	}
	~SList()    //析构
	{
		Clear();
	}

public:
	void PrintSList()    //打印链表
	{
		//头结点为空时,无需打印链表
		if (_head==NULL)
		{
			cout << "This SList is Empty !" << endl;
			return;
		}
		else
		{
			LinkNode* tmp = _head;
			do{ 
				cout << tmp->_data << "-->";
				tmp = tmp->_next;
			    } while (tmp != _head);
			cout << endl;
		}
	}
	void PushBack(const DataType& x)    //在尾部插入一个节点
	{
		//如果链表为空,插入节点后只有一个节点,此时_head=_tail
		if (_head == NULL)
		{
			_head = new LinkNode(x);
			_tail = _head;
			_tail->_next = _head;
		}
		else
		{
			_tail->_next = new LinkNode(x);
			_tail = _tail->_next;
			_tail->_next = _head;
		}
	}
	void Clear()         //链表置空
	{
		LinkNode* begin = _head;
		while (begin != _tail)
		{
			_head = _head->_next;
			delete begin;
			begin = _head;
		}
		_head = NULL;
		_tail = NULL;
	}
	void PopBack()    //尾删
	{
		if (_head == NULL)
		{
			cout << "This SList is empty !" << endl;
		}
		else if (_head == _tail)
		{
			delete _head;
			_head = NULL;
			_tail = NULL;
		}
		else
		{
			LinkNode* cur = _head;
			while (cur->_next != _tail)
			{
				cur = cur->_next;
			}
			delete _tail;
			_tail = cur;
			_tail->_next = _head;
	     }
	}
	void PushFront(DataType x)  //头插
	{
		if (_head == NULL)
		{
			PushBack(x);
		}
		else
		{
			LinkNode* tmp = _head;
			_head = new LinkNode(x);
			_head->_next = tmp;
			_tail->_next = _head;
		}
	}
	void PopFront()    //删除首节点
	{
		if (_head == NULL)
		{
			cout << "This SList is empty !" << endl;
			return;
		}
		LinkNode* tmp = _head;
	
		_tail->_next = _head;
		delete tmp;
	}

	//固定位置插入一个节点(这个函数需和Find函数搭配使用)
	//先用Find函数找到新节点需要插入的位置,即
	//(将Find函数的返回值传给Insert函数的参数pos),再在pos节点后面插入新节点x
	void Insert(LinkNode* pos, DataType x)       
	{
		assert(pos);
		if (pos==_tail)
		{
			PushBack(x);
		}
		else
		{
			LinkNode* tmp = new LinkNode(x);
			tmp->_next = pos->_next;
			pos->_next = tmp;
		}
	}
        //删除某一节点,同样,要先找到该节点并传参给Erase函数
	void Erase(LinkNode* pos)        
	{
		assert(pos);
		if (pos == _tail)
		{
			PopBack();
		}
		if (pos == _head)
		{
			PopFront();
		}
		else
		{
			LinkNode* prev = _head;
			while (prev->_next != pos)
			{
				prev = prev->_next;
			}
			prev->_next = pos->_next;
			delete pos;
		}
	}
	LinkNode* Find(DataType x)       //查找节点并返回这个节点的地址
	{
		if (_head == NULL)
		{
			cout << "This SList is empty !" << endl;
			return NULL;
		}
		else
		{
			LinkNode* tmp = _head;
			do{
					if (tmp->_data == x)
					{
						return tmp;
					}
						tmp = tmp->_next;
			} while (tmp != _head);
			return NULL;
		}
	}
	int Amount()   //计算链表节点的数目
	{
		if (_head == NULL)
		{
			return 0;
		}
		else
		{
			int count = 0;
			LinkNode* cur = _head;
			while (cur != _tail)
			{
				count++;
				cur = cur->_next;
			}
			return ++count;
		}
	}
	void Remove(DataType x)      //查找某节点并删除
	{
		if (_head == NULL)
		{
			cout << "This SList is empty !" << endl;
		}
		else
		{
			LinkNode* tmp = Find(x);
			if (tmp != NULL)
			{
				Erase(tmp);
			}
		}
	}
	void RemoveAll(DataType x)       //删除链表中所有的x
	{
		if (_head == NULL)
		{
			cout << "This SList is empty !" << endl;
			return;
		}
          //如果链表不为空,
         //从头至尾遍历一遍,delete节点的data为x的节点
			LinkNode* left = _tail;
			LinkNode* right = _head;
			int count = Amount();
			while (count--)
			{
				if (right->_data == x)
				{
				     //当要删掉的节点是头节点时,
				     //需要注意头节点要指向它的下一个节点
					if (_head == right)   
					{
						_head = _head->_next;
					}
					 //当要删掉的节点是尾节点时,
					 //需要注意尾节点要指向它的上一个节点
					if (_tail == right)  
					{
						_tail =left;
					}
					 //当left和right指向同一块要删掉的节点时,
					 //将链表置空
					if (right == left)    
					{
						_head = NULL;
						_tail = NULL;
						return;
					}
					LinkNode* tmp = right;
					right = right->_next;
					delete tmp;
					left->_next = right;
				}
				else
				{
					left = right;
					right = right->_next;
				}
			}	
	}

private:
	LinkNode* _head;
	LinkNode* _tail;
};

void Test2()
{
	SList list1;
	list1.PushBack(2);
	list1.PushBack(3);
	list1.PushBack(4);
	list1.PushBack(2);
	list1.PushBack(2);
	list1.PrintSList();

	list1.RemoveAll(2);
	list1.PrintSList();
}
void Test1()
{
	//SList list1;
	//list1.PushBack(1);
	//list1.PushBack(2);
	//list1.PushBack(3);
	//list1.PushBack(4);
	//list1.PushBack(5);
	//list1.PrintSList();

	//list1.Remove(2);
	//list1.PrintSList();

	//int num =list1.Amount();
	//cout <<"节点个数:"<< num << endl;

	/*//检验Erase函数
	LinkNode* del = list1.Find(2);
	list1.Erase(del);
	list1.PrintSList();
	*/

	/*//找到某节点并在其后插入新节点
	LinkNode* In =list1.Find(5);
	list1.Insert(In, 0);
	list1.PrintSList();*/

	/* //删除头结点
	list1.PopFront();
	list1.PrintSList();
	*//////

	/*//////查找节点
	LinkNode* ret=list1.Find(5);
	if (ret != NULL)
	{
		cout << "要查找的节点data是:" << ret->_data << endl;
		cout << "要查找的节点adress是:" <<ret<< endl;
	}
	else
	{
		cout << "not exit !" << endl;
	}*////////

	//验证构造函数
	//SList list2(list1);
	//list2.PrintSList();

	//验证赋值运算符的重载
	//SList list3 = list2;
	//list3.PrintSList();

	//验证析构函数
	//list3.Clear();
	//list3.PrintSList();

	//验证尾删和头插
	///*list3.PopBack();
	//list3.PrintSList();*/
	//list3.PushFront(0);
	//list3.PrintSList();
}

int main()
{
	//Test1();
	Test2();
	system("pause");
}


本文出自 “言安阳” 博客,谢绝转载!

C++实现单链表

标签:c++      单链表   

原文地址:http://iynu17.blog.51cto.com/10734157/1752937

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!