自己写的一个单链表模版,模版的实现和定义是不可以分开两个文件写的 和平时写的类的不太一样 这个要注意,一开始没注意到这个 就出现了那个最讨厌的 unresolve external symbol 的错误 下面是代码 功能是一些比较常见的功能
这个是经过修改完善后的一个最终版本,以后有新想法 会再添加进去
mylist.h文件
#include<iostream.h>
template<class T>
class My_list;
template<class T>
class Node //节点类
{
private:
T data;
Node<T> *next;
public:
Node()
{
next=NULL;
}
Node(T d)
{
data=d;
next=NULL;
}
friend My_list<T>;//声明为友元,在链表类中访问节点类的私有成员
};
template<class T>
class My_list
{
private:
Node<T> *head,*tail;
static bool flag;//判断是否已经排序的标志
public:
My_list()
{
head=tail=new Node<T>();
}
~My_list()
{
clean();
delete head;
cout<<"析构函数~"<<endl;
}
Node<T> *create(T d)//创建节点
{
Node<T> *p=new Node<T>(d);
return p;
}
void insert_front(Node<T> *p)//头插入
{
p->next=head->next;
head->next=p;
}
void insert_rear(Node<T> *p)//尾插入
{
tail->next=p;
tail=p;
}
bool empty()//判断链表是否为空
{
return (head->next==0);
}
int length()//计算表长
{
int size=0;
Node<T> *p=head->next;
while(p)
{
size++;
p=p->next;
}
return size;
}
bool retrive(int k, T& x)//由x来返回k位置处的值
{
int pos=1;
Node<T> *p=head->next;
while(pos<k && p)
{
pos++;
p=p->next;
}
if(!p && pos<=k)
return false;
else
{
x=p->data;
return true;
}
}
int locate(const T& x)//返回x在表中位置,找不到返回0
{
int pos=1;
Node<T> *p=head->next;
while(p->data!=x && p->next)
{
p=p->next;
pos++;
}
if(!p || p->data!=x)
pos=0;
return pos;
}
bool insert(int k,T x)//在k位置后面插入x
{
if(k<0 || k>length())
return false;
int i=1;
Node<T> *p=head->next;
Node<T> *temp=new Node<T>(x);
if(k==0)//插在头结点之后
{
temp->next=head->next;
head->next=temp;
}
else
{
while(i<k && p)
{
i++;
p=p->next;
}
temp->next=p->next;
p->next=temp;
}
return true;
}
bool erase(int k,T& x)//删除k位置的节点,将k处的值给x
{
int i=1;
Node<T> *p=head->next;
if(k==1)
{
head->next=p->next;
x=p->data;
delete p;
return true;
}
while(i<k-1 && p)
{
i++;
p=p->next;
}
if(!p->next && i<=k-1)
return false;
else
{
Node<T> *temp=p->next;//temp指向k处节点
p->next=temp->next;
x=temp->data;
delete temp;
return true;
}
}
void print_list() const//输出表
{
Node<T> *p=head->next;
if(!p)
{
cout<<"List is empty."<<endl;
return ;
}
while(p)
{
cout<<p->data<<'\t';
p=p->next;
}
cout<<endl;
}
void clean()//删除整条链,表头结点在,那个由析构函数回收
{
Node<T> *p=head->next;
while(p)
{
head->next=p->next;
delete p;
p=head->next;
}
}
void select_sort()//用选择排序进行排序按升序排列
{
Node<T> *p,*q,*r;
int t1,t2;
p=head->next;
while(p)
{
t1=p->data;
q=p->next;
while(q)
{
if(t1>q->data)
{
t1=q->data;
r=q;
}
q=q->next;
}
if(t1!=p->data)
{
t2=p->data;
p->data=t1;
r->data=t2;
}
p=p->next;
}
flag=true;
}
void unique()//删除值重复的节点
{
if(!flag)
select_sort();
Node<T> *p=head->next;
while(p->next)
{
while(p->data==p->next->data)
{
Node<T> *q=p->next;
p->next=q->next;
delete q;
}
p=p->next;
}
}
bool inverse()//逆置整条链
{
Node<T> *p=head->next;
Node<T> *tail=NULL,*r;
while(p)
{
r=p->next;
p->next=tail;
tail=p;
p=r;
}
head->next=tail;
return true;
}
};
template<class T>
bool My_list<T>::flag=false;
下面是一个测试代码 mian.cpp
#include"mylist.h"
int main()
{
My_list<int> list;
if(list.empty())
cout<<"list is empty"<<endl;
Node<int> *p;
int x;
while((cin>>x) && (x!=0))
{
p=list.create(x);
list.insert_rear(p);
}
list.print_list();
p=list.create(9);
list.insert_front(p);
list.print_list();
cout<<"表长为:"<<list.length()<<endl;
int pos;
cout<<"输入要返回哪个位置:";
cin>>pos;
if(list.retrive(pos,x))
cout<<x<<endl;
int t,xx;
cout<<"输入要返回哪个值的位置:";
cin>>t;
xx=list.locate(t);
if(xx)
cout<<xx<<endl;
else
cout<<"No find"<<endl;
cout<<"输入要插入数字的位置和数值"<<endl;
cout<<"位置:";
cin>>pos;
cout<<"值:";
cin>>t;
if(list.insert(pos,t))
cout<<"insert is successful."<<endl;
else
cout<<"insert is fail."<<endl;
list.print_list();
int tt;
cout<<"输入要删除的位置:";
cin>>pos;
if(list.erase(pos,tt))
cout<<tt<<endl;
list.print_list();
list.select_sort();
list.print_list();
list.unique();
list.print_list();
cout<<"_______逆置_______"<<endl;
if(list.inverse())
cout<<"逆置成功"<<endl;
list.print_list();
cout<<"______清空表______"<<endl;
list.clean();
if(list.empty())
cout<<"清空完成"<<endl;
return 0;
}