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;
}