链表的实现

单向链表的实现
链表是一种广泛使用的保存数据的数据结构,涉及查找,增加,删除,匹配遍历等:
定义如下:
template<typename T>
class node{
public:
T ele;
node<T>*next;
node(){next=NULL;}
node(T ele){this->ele=ele;next=NULL;}};
 
template<typename T>
class linklist{
private:
node<T> *head;
node<T> *before;
int size;
public:
	linklist(){head=NULL;before=NULL;size=0;}
void addfirst(T ele);//将元素添加到链表头
void addlast(T ele);//将元素添加到链表尾
T getfirst();//返回链表头元素
T getlast();//返回链表尾元素
T removefirst();//删除链表头元素
T removelast();//删除链表尾元素
void add(T ele);//将一个新元素附加到列表表尾
void add(int index,T ele);//将一个新元素附加到列表指定位置
void clear();//删除列表所有元素
bool con(T ele);//判断元素是否存在于链表
T get(int index);//返回指定位置处元素
int get1stindex(T ele);//返回列表里第一次匹配的下标
bool empty();//判断空
int getlastindex(T ele);//返回列表里最后一次匹配的下标
void remove(T ele);//删除链表指定元素
int getsize();//返回链表元素数目
T remove(int index);//删除链表指定位置元素并返回
T set(int index,T ele);//设置index为新值ele,并返回旧值
void addall(linklist<T>&l1);//把另一个链表元素加入到该链表之后
void removeall(linklist<T>&l1);//从该链表中减去所有l1中元素
void retailall(linklist<T>&l1);//保留两个链表的交集};
template<typename T>
void linklist<T>::addfirst(T ele){
node<T> *newnode=new node<T>(ele);
newnode->next=head;//插入头
head=newnode;//head指向新节点
size++;
if(before==NULL) before=head;//如果列表原来是空,则尾节点指向头
}//将元素添加到链表头
template<typename T>
void linklist<T>::addlast(T ele){
	node<T> *newnode=new node<T>(ele);
node<T>*p=head;
if(before==NULL){head=before=newnode;}//如果列表为空,则head=before指向新节点
else {before->next=newnode;
before=before->next;}//否则插入表尾
size++;}//将元素添加到链表尾
template<typename T>
T linklist<T>::getfirst(){
if(empty()) throw runtime_error("empty");
return head->ele;}//返回链表头元素
template<typename T>
T linklist<T>::getlast(){
if(empty()) throw runtime_error("empty");
else return before->ele;}//返回链表尾元素
template<typename T>
T linklist<T>::removefirst(){
if(empty()) throw runtime_error("empty");//链表为空,抛出异常
else{
node<T>*p=head;
head=p->next;//否则头节点删除
if(head==NULL)before=NULL;//如果链表原来只有一个元素,删除后将before=NULL
size--;
T ele=p->ele;
delete p;
return ele;
}}//删除链表头元素
template<typename T>
T linklist<T>::removelast(){
if(empty()) throw runtime_error("empty");//链表为空,抛出异常
else if(size==1){
node<T> *p=head;
head=before=NULL;
size--;
T ele=p->ele;
delete p;
return ele;}//列表只有一个元素时
else {
node<T>*p=head;
for(int i=0;i<size-2;i++)
	p=p->next;//将p定位于倒数第二个节点
T ele=before->ele;
before=p;
before->next=NULL;
size--;
//delete p;
return ele;}
}//删除链表尾元素
template<typename T>
void linklist<T>::add(T ele){
addlast(ele);}//将一个新元素附加到列表表尾
template<typename T>
void linklist<T>::add(int index,T ele){
if(index==0) addfirst(ele);//头部插入
else if(index>=size) addlast(ele);//尾部插入
else {
node<T>*p=head;
for(int i=0;i<index;i++)
  p=p->next;//p定位到index
node<T> *newnode=new node<T>(ele);
newnode->next=p->next;
p->next=newnode;//?
size++;//index处插入
}}//将一个新元素附加到列表指定位置
template<typename T>
void linklist<T>::clear(){
while(head!=NULL){
node<T>*p=head;
delete p;
head=head->next;}
before=NULL;}//删除列表所有元素
template<typename T>
bool linklist<T>::con(T ele){
int f=0;
int k=0;
node<T>*p=head;
before=NULL;
while(p!=NULL){
	f=0;
	if(ele==p->ele)  {f=1;k++;}
    if(f==1) return true;
	p=p->next;}
if(k==0) return false;}//判断元素是否存在于链表
template<typename T>
T linklist<T>::get(int index){
	if(index<0||index>=size) throw runtime_error("index error");
node<T>*p=head;
for(int i=0;i<index;i++)//定位到index
	p=p->next;
T ele=p->ele;
//delete p;
return ele;}//返回指定位置处元素
template<typename T>
int linklist<T>::get1stindex(T ele){
int f=0;
int k1=0;
int k=0;
node<T>*p=head;
before=NULL;
while(p!=NULL){
	f=0;
	if(ele==p->ele) {f=1;k1++;break;}
	k++;
    before=p;
	p=p->next;}
if(f==1) return k;
if(k1==0) return -1;}//返回列表里第一次匹配的下标
template<typename T>
bool linklist<T>::empty(){
if(size==0||head==NULL) return true;
else return false;}//判断空
template<typename T>
int linklist<T>::getlastindex(T ele){
int i;
int f=0;
vector<int> index;
node<T>*p=head;
for(i=0;i<size;i++){
	if(ele==p->ele){f++;index.push_back(i);continue;}
    p=p->next;}
if(f==0) return -1;
else{return index.at(f-1);
}}//返回列表里最后一次匹配的下标
template<typename T>
void linklist<T>::remove(T ele){
int f=0;
int k=0;
node<T>*p=head;
before=NULL;
while(p!=NULL){
	f=0;
	if(ele==p->ele) {f=1;k++;break;}
before=p;
p=p->next;}
if(f==1) {
	if(before==NULL) { head=p->next;size--;}
	else {before->next=p->next;size--;}}
if(k==0) cout<<"no "<<ele<<endl;
}//删除链表指定元素
template<typename T>
int linklist<T>::getsize(){
return size;}//返回链表元素数目
template<typename T>
T linklist<T>::remove(int index){
if(index<0||index>=size) throw runtime_error("index error");
else if(index==0) return removefirst();
else if(index==size-1) return removelast();
else{
node<T>*p=head;
for(int i=0;i<index;i++)
	p=p->next;
T ele=p->next->ele;
p->next=p->next->next;
size--;
//delete p;
return ele;}}//删除链表指定位置元素并返回
template<typename T>
T linklist<T>::set(int index,T ele){
<span style="white-space:pre">	</span>T ele1=remove(index-1);
add(index-1,ele);
return ele1;}//设置index为新值ele,并返回旧值
template<typename T>
void linklist<T>::addall(linklist<T>&l1){
<span style="white-space:pre">	</span>int len=l1.getsize();
for(int i=0;i<len;i++)
    addlast(l1.get(i));
}//把另一个链表元素加入到该链表之后
template<typename T>
void linklist<T>::removeall(linklist<T>&l1){
<span style="white-space:pre">	</span>int len=l1.getsize();
<span style="white-space:pre">	</span>vector<int>vv;
int i,j;
int f=0;
int k=0;
for(i=0;i<len;i++){
<span style="white-space:pre">	</span>for(j=0;j<size;j++){f=0;
<span style="white-space:pre">	</span>if(get(j)==l1.get(i)) {
<span style="white-space:pre">		</span>f=1;k++;vv.push_back(i);}
}
<span style="white-space:pre">	</span>if(f==1) for(i=0;i<k;i++)remove(l1.get(vv.at(i)));<span style="white-space:pre">	</span>//if(k==0)  cout<<"no the same"<<endl;
}}//从该链表中减去所有l1中元素
template<typename T>
void linklist<T>::retailall(linklist<T>&l1){
<span style="white-space:pre">	</span>linklist<T>l2;
<span style="white-space:pre">	</span>int len=l1.getsize();
int i;
int f=0;
int k=0;
for(int i=0;i<len;i++)
<span style="white-space:pre">	</span>if(con(l1.get(i))){k++; l2.add(l1.get(i));}
for(i=0;i<k;i++){
cout<<(l2.get(i))<<" ";}
}//保留两个链表的交集
主函数调用:
template<typename T>
void disp(linklist<T>&e){
	for(int i=0;i<e.getsize();i++)
		cout<<e.get(i)<<" ";
cout<<endl;}
int main(){
linklist<string> li;
li.addfirst("America");
cout<<"(1)";
disp(li);
li.add(0,"Canada");
cout<<"(2)";
disp(li);
li.add("Russia");
cout<<"(3)";
disp(li);
li.add("France");
cout<<"(4)";
disp(li);
li.add(2,"Germany");
cout<<"(5)";
disp(li);
li.add(5,"Norway");
cout<<"(6)";
disp(li);
li.add(0,"Nertherland");
cout<<"(7)";
disp(li);
li.add("France");
cout<<"(8)";
disp(li);
cout<<li.con("Canadwa")<<endl;
cout<<li.get1stindex("France")<<endl;
cout<<li.getlastindex("France")<<endl;
li.remove("Canada");
disp(li);
//li.set(6,"France");
//disp(li);
li.remove(0);
cout<<"(8)";
disp(li);
li.remove(2);
cout<<"(9)";
disp(li);
li.remove(li.getsize()-1);
cout<<"(10)";
disp(li);
system("pause");
return 0;}
结果:

现在,如果需要保存数据,既可以数组也可以链表。如果预先不知道元素数目,使用链表最好,因为链表可以动态增减;如果频繁进行增减等操作,也推荐链表,因为数组的增减需要遍历所有元素效率低。当然当元素数目已知固定而且不需要大量增减时候,数组是首选。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值