CList模板链表

STL为我们提供了各种容器,像vector、list、stack、deque、array、map,其模板的泛型化更是极大地方便了程序的编写过程。

以STL中的list为例,它为我们提供了许多操作,如下图:


其中包括我们经常要使用的一些链表方法能像push_back、push_front 、insert、remove、size、reverse等。

下面代码为 CList模板类,实现list的主要的功能,以加深模板编程的理解。

/**CList.h
*date 2017-7-11
*@author xwz
*compiler: Dev c++
*/

#ifndef CLIST_H_
#define CLIST_H_

template<class T>
class CList {
	 typedef struct ListNode 
	 {
		 T val;							//数据域 
		 struct ListNode *next;			//指针域 
		 ListNode(T x) :				 
				val(x), next(NULL){}  
	 }ListNode;
	 
	ListNode* m_pHead;			//头结点		
	int m_length;				//链表长度 
	
public:
	CList():m_pHead(NULL),m_length(0)
	{
		
	}
	
	void AddTail(const T val)
	{
		//在链表尾部添加值为val的新结点 
		ListNode *newnode = new ListNode(val);
		if(!m_pHead)
			m_pHead = newnode;
		else
		{
			ListNode *p = m_pHead;
			while(p->next)
				p=p->next;
			p->next=newnode;	
		}	
		++m_length;
	}
	
	void AddHead(const T val)
	{
		//在链表头部添加值为val的新结点 
		ListNode *newnode = new ListNode(val);
		if(!m_pHead)
			m_pHead = newnode;
		else
		{
			newnode->next = m_pHead;
			m_pHead=newnode;
		}	
		++m_length;
	}
	
	~CList()
	{
		if(m_pHead)
		{
			ListNode* temp;
			while(m_pHead->next)
			{
				temp=m_pHead;
				m_pHead=m_pHead->next;
				delete temp;
			}
			delete m_pHead;
			m_pHead = NULL;	
		}
	}
	
	int GetLength() const
	{
		return m_length;
	}
	
	bool Empty() const
	{
		return m_length == 0;
	}
	
	void Print() const
	{
		//打印链表 
	   if(m_pHead)
	   {
		   ListNode *p = m_pHead;
		   while(p)
		   {
			   cout << p->val << " ";
			   p=p->next;
		   }
	   }	
	   cout << endl;
	}

	void Erase(int pos)
	{	
		//删除链表中第pos个结点 
		if(m_pHead && pos < m_length+1 && pos>0)
		{
			int i=1;
			ListNode *temp,*p=m_pHead;
				while(i<=m_length && p)
				{
					if(i == pos)
						break;
					++i;
					temp=p;				//记住前驱结点
					p=p->next;
				}
				if(i==1)
					m_pHead = m_pHead->next;
				else
					temp->next = p->next;
				delete p;
				--m_length;
			}
	}	
	
	void Remove(const T val)
	{
		//删除链表中值为val的结点 
		if(m_pHead)
		{
			ListNode *temp,*p = m_pHead;
			while(p)
			{
				if(p->val == val)				
					break;
				temp = p;		//记下前驱结点 
				p=p->next;
			} 
			if(p == m_pHead)
				m_pHead = m_pHead->next;
			else
				temp->next = p->next;
			
			delete p;
			--m_length;
		}
	}
	
	void Insert(int pos,const T val)
	{
		//在链表第pos个结点处插入值为val的新结点 
		cout << m_length << endl;
		if(m_pHead && pos < m_length+1 && pos>0)
		{
			ListNode *newnode = new ListNode(val);		//新建插入结点 
			if(pos == 1)	//插在第一个结点 
			{
				newnode->next = m_pHead;
				m_pHead = newnode;
			}
			else
			{
				int i=1;
				ListNode *temp,*p = m_pHead; 
				while(i<=m_length && p)
				{
					if(i==pos)
						break;
					temp = p;
					p = p->next;
					++i; 
				}
				
				newnode->next = p;
				temp->next=newnode;
			} 
			++m_length;
		}
	}
	
	void Reverse()
	{//链表转置 
	//	将头接点的后的每个接点都放再头接点的前面。直到头接点到达
	//  尾接点
		ListNode *cur = m_pHead;
		ListNode *pLeft = NULL;
		ListNode *pRight = NULL;
		
		while(cur)
		{
			pRight = cur->next;		//记录当前结点的下一个结点 
			cur->next = pLeft;
			pLeft = cur;
			cur = pRight;				//当前指针后移 
		}
		m_pHead = pLeft;				//修改转置后的头结点位置 
	}
	

};

#endif // !CLIST_H_

测试代码:

//test.cpp
#include<iostream>
#include"CList.h"
using namespace std;

int main()
{ 
	CList<string> s;
	s.AddTail("beijing");
	s.AddTail("shanghai");
	s.AddTail("changsha");
	s.AddTail("henyang");
	s.AddTail("gaungzhou");


//	s.Remove("gaungzhou");
//	s.Remove("shanghai");
	//s.Insert(5,"wuhan");
	s.Print();
	s.Erase(5);
	s.Print();
	
	CList<int> s2;
	s2.AddHead(4);
	s2.AddHead(3);
	s2.AddHead(2);
	s2.AddHead(1);
	s2.AddHead(0);
	s2.AddTail(5); 
	
	s2.Print();
	s2.Reverse();
	s2.Print();
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值