单链表是在物理存储上非连续非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接的,链表是由一个个节点组成,每个节点包括数据域和指针域,指针域指向下个节点的地址,因为链表是由节点组成,节点可以不断的增加,所以链表的大小是动态的,单链表的数据访问只能通过遍历整个链表所以时间复杂度是O(n)但在删除插入等操作时的时间复杂度O(1)
#include <iostream>
using namespace std;
template <class T>
struct node
{
T date; //数据域
node *next; //指针域
};
template <class T>
class linklist
{
private:
node<T> *first;
public:
linklist();//生成一个长度为0的单链表
linklist(T a[],int &n);//生成一个长度为n的单链表
~linklist();//销毁单链表
int Length();//返回单链表的长度
int GET(int &i);//返回单链表位置i的数据
int locate(T &x);//返回单链表中x数据的位置
void Insert(int &i,T &x);//在位置i处插入x
void Delete(T &i);//删除位置i处的数据
void Printlist();//打印单链表
};
template <class T>
linklist<T>::linklist()
{
first=new node<T>;
first->next=NULL;
}
template <class T>
linklist<T>::linklist(T a[],int &n)//尾插法按原本的顺序生成链表
{
first=new node<T>;
node<T> *r=first,*s=NULL;
for(int i=0;i<n;i++)
{
s=new node<T>;
r->next=s;
s->date=a[i];
r=s;
}
r->next=NULL;
}
/*
template <class T>
linklist<T>::linklist(T a[],int &n)//头插法按原本顺序的倒序生成链表
{
first=new node<T>
for(int i=0;i<n;i++)
{
node<T> *s=new node<T>;
s->next=first->next;
s->date=a[i];
first->next=s;
}
}
*/
template <class T>
linklist<T>::~linklist()
{
node<T> *p=first;
while(first!=NULL)
{
first=first->next;
delete p;
p=first;
}
}
template <class T>
int linklist<T>::Length()
{
node<T> *p=first->next;
int num=0;
while(p!=NULL)
{
num++;
p=p->next;
}
return num;
}
template <class T>
int linklist<T>::GET(int &i)
{
node<T> *p=first->next;
int sum=1;
while(p!=NULL&&sum<i)
{
p=p->next;
sum++;
}
if(p==NULL)
{
cout<<"查找位置错误"<<endl;
return 0;
}
else
{
cout<<p->date<<endl;
return 1;
}
}
template <class T>
int linklist<T>::locate(T &x)
{
node<T> *p=first->next;
int num=1;
while(p!=NULL)
{
if(p->date==x)
{
return num;
}
num++;
p=p->next;
}
return 0;
}
template <class T>
void linklist<T>::Insert(int &i,T &x)
{
node<T> *p=first->next;
int num=1;
while(p!=NULL&&num<i-1)
{
num++;
p=p->next;
}
if(p==NULL)
cout<<"插入失败"<<endl;
else
{
node<T> *n=new node<T>;
n->next=p->next;
p->next=n;
n->date=x;
}
}
template <class T>
void linklist<T>::Delete(T &i)
{
node<T> *p=first->next;
int sum=1;
while(p!=NULL&&sum<i-1)
{
p=p->next;
sum++;
}
if(p==NULL||p->next==NULL)
{
cout<<"删除位置不存在"<<endl;
}
else
{
node<T> *q=NULL;
q=p->next;
p->next=q->next;
delete q;
}
}
template <class T>
void linklist<T>::Printlist()
{
node<T> *p=first->next;
while(p!=NULL)
{
cout<<p->date<<" ";
p=p->next;
}
cout<<endl;
}
int main()
{
int text1[]={1,2,3,4,5,6,7,8,9},n=9,n1=10;
linklist<int> text(text1,n);
text.Printlist();
cout<<text.Length()<<endl;
text.GET(n);
n=5;
cout<<text.locate(n)<<endl;
n=8;
text.Insert(n,n1);
text.Printlist();
n=7;
text.Delete(n);
text.Printlist();
return 0;
}
测试结果如下
1 2 3 4 5 6 7 8 9
9
9
5
1 2 3 4 5 6 7 10 8 9
1 2 3 4 5 6 10 8 9
Process returned 0 (0x0) execution time : 0.035 s
Press any key to continue.
综上所述如果在不知道数据的大小,或者需要大量的插入删除等操作的话,链表是一个可以提高效率的方法之一。
要注意写的过程中避免野指针。