链表的模板实现,我在上面有非常详细的标注
/*
链表和数组是一个非常重要的数据结构,常用于实现队列,堆栈,二叉树等数据结构
所以请大家一定要掌握链表和数据的特性
实现方式:在一个头文件中以完整的方式
实现链表模板
链表功能:
1.初始化链表
2.是否为空?
3.遍历链表输出
4.得到链表长度
5.销毁链表
6.得到首结点的数据
7.得到尾结点的数据
8.查找指定的项
9.插入项
10.删除项
11.复制一个链表
*/
//linkdlist.h file
//首先定义一个链表结构
#define NUll 0
template<class T>
struct nodetype
{
T info;
nodetype<T> *link;
};
//ADT链表类模板总定义
template<class T>
class linkdlist
{
friend ostream& operator<<(ostream&,const linkdlist<T>&);
//遍历输出链表所有结点
public:
const linkdlist<T>& operator=(const linkdlist<T>&);
//重载=
void initlist();
//功能:初始化函数
//前置:NULL
//后置: first=NUll;last=NULL;count=0;
bool isempty();
//功能:检查是否为空
//前置:NULL
//后置: 如空则return TRUE,否则return FALSE;
int length();
//功能:得到链表的长度
//前置:链表必须存在
//后置: 返回链表的count
void destroylist();
//功能:删除链表中所有的结点
//前置:链表必须存在
//后置:first=NUll;last=NULL;count=0;
T front();
//功能:返回第一个结点数据
//前置:链表必须存在并且不能是空表
//后置:如链表为空则程序中止,否则返回第一个结点数据
T back();
//功能:返回第一个结点数据
//前置:链表必须存在并且不能是空表
//后置:如链表为空则程序中止,否则返回第一个结点数据
bool search(const T& searchitem);
//功能:检查给定数据是存在于链表中
//前置:链表必须存在并且不能是空表
//后置:存在就返回TRUE,不存在就返回FALSE
void insertfirst(const T& newitem);
//功能:插入新项到链表头部
//前置:链表必须存在
//后置:链表尾结点重新指向链表未尾,count加1
void insertlast(const T& newitem);
//功能:插入新项到链表尾部
//前置:链表必须存在
//后置:链表尾结点重新指向链表未尾,count加1
void deletenode(const T& deleteitem);
//功能:从链表中删除一个结点
//前置:链表必须存在
//后置:先用search()检查是否存在?,存在则删除,
//链表尾结点重新指向链表未尾,count减1
linkdlist();
//功能:链表模板的缺省构造函数
//前置:初始化一个链表,调用initlist();
//后置:first=NUll;last=NULL;count=0;
linkdlist(const linkdlist<T>&otherlist);
//功能:复制构造函数
~linkdlist();
//功能:析构函数
//前置:NULL;调用destroylist();
//后置:把内存中的链表所有的结点删除
void print();
//功能:打印所有结点数据
//前置:NULL
//后置:把链表所有的结点打印出来
protected:
int count; //链表长度
nodetype<T> *first; //链表首结点
nodetype<T> *last; //链表尾结点
private:
void copylist(const linkdlist<T>&otherlist);
//功能:复制链表数据到另一个链表
//前置:链表必须存在并且不能是空表
//后置:用this链表去建立另一个链表对象
};
//友元函数实现
template<class T>
ostream& operator<<(ostream& osobject,const linkdlist<T>& list)
{
nodetype<T> *current;
current=list.first;
while(current!=NULL)
{
osobject<<current->info<<" ";
current=current->link;
}
return osobject;
}
//类函数的实现代码
//检查是否为空,时间复杂度为 O(1)
template<class T>
bool linkdlist<T>::isempty()
{return (first==NULL);}
//缺省的构造函数,时间复杂度为 O(1)
template<class T>
linkdlist<T>::linkdlist()
{
first=NUll;
last=NULL;
count=0;
}
//缺省的构造函数,时间复杂度为 O(n)
template<class T>
void linkdlist<T>::destroylist()
{
nodetype<T> *temp;
while(first!=NULL)
{ //删除方法:从链表的首结点往尾部方向删除
temp=first; //把首结点存入临时结点temp
first=first->link; //首结点指到下一个结点,首结点就脱离链表
delete temp; //删除刚才指向首结点的temp
temp=NULL; //置temp指针为空,以防止内存访问出错
}
//首尾结点置NULL,结点数量为0
first=NULL;
last=NULL;
count=0;
}
//初始化链表,时间复杂度为 O(n)
template<class T>
void linkdlist<T>::initlist()
{destroylist();}
//功能:得到链表的长度,时间复杂度为 O(1)
template<class T>
int linkdlist<T>::length()
{return count;}
//功能:返回第一个结点数据,时间复杂度为 O(1)
template<class T>
T linkdlist<T>::front()
{
assert(last!=NULL);
return first->info;
}
//功能:返回第一个结点数据,时间复杂度为 O(1)
template<class T>
T linkdlist<T>::back()
{
assert(last!=NULL);
return last->info;
}
//功能:检查给定数据是存在于链表中,时间复杂度为 O(n)
template<class T>
bool linkdlist<T>::search(const T& searchitem)
{
nodetype<T> *current;
bool found;
found=false;
current=first;
while(current!=NULL && !found)
{
if (current->info==searchitem)
found=true;
else
current=current->link;
}
return found;
}
//功能:插入新项到链表头部,时间复杂度为 O(1)
template<class T>
void linkdlist<T>::insertfirst(const T& newitem)
{
nodetype<T> *newnode;
newnode=new nodetype<T>;
assert(newnode!=NULL);
newnode->info=newitem;
newnode->link=first;
count++;
if (last==NULL)
last=NULL;
}
//功能:插入新项到链表尾部,时间复杂度为 O(1)
template<class T>
void linkdlist<T>::insertlast(const T& newitem)
{
nodetype<T> *newnode;
newnode=new nodetype<T>;
assert(newnode!=NULL);
newnode->info=newitem;
newnode->link=first;
if (last==NULL)
{
first=newnode;
last=newnode;
count++;
}
else
{
last=newnode;
last->link=newnode;
count++;
}
}
//功能:从链表中删除一个结点 O(n)
template<class T>
void linkdlist<T>::deletenode(const T& deleteitem)
{
nodetype<T> *current,*trailcurrent;
bool found;
if (first!=NULL) //case1:是一个空链表
cout<<"cannot delete a empty list/n";
else
{
if(first->info==deleteitem)//case2:
{
current=first;
first=first->link;
//delete current;
count--;
if (first==NULL)
{
last=NULL;
delete current;
}
else
{
found=false;
trailcurrent=first;
current=first->link;
while(current!=NULL && !found)
{
if(current->info!=deleteitem)
{
trailcurrent=current;
current=current->link;
}
else
found=true;
}//end while
if (found)
{
trailcurrent->link=current->link;
count--;
if (last==current)
last=trailcurrent;
delete current;
}
else
cout<<"item is not be in list./n";
}//end else
}//end else
}
}
//功能:复制链表数据到另一个链表 O(n)
template<class T>
void linkdlist<T>::copylist(const linkdlist<T>&otherlist)
{
nodetype<T> *current,*newnode;
if(first!=NULL)
destroylist();
if(otherlist.first==NULL)
{
first=NULL;
last=NULL;
count=0;
}
else
{
current =otherlist.first;
count =otherlist.count;
//copy first node
first=new nodetype<T>;
assert(first!=NULL);
first->info=current->info;
first->link=NULL;
last=first;
current=current->link;
//copy 所有结点
while(current!=NULL)
{
newnode =new nodetype<T>;
assert(newnode!=NULL);
newnode->info=current->info;
newnode->link=NULL;
last->link=newnode;
last=newnode;
current=current->link;
}//end while
}//end else
}//end copylist
//功能:析构函数
//前置:NULL;调用copylist();
template<class T>
linkdlist<T>::~linkdlist()
{
destroylist();
}
//功能:复制构造函数
//前置:NULL;调用destroylist();
template<class T>
linkdlist<T>::linkdlist(const linkdlist<T>& otherlist)
{
first=NULL;
copylist(otherlist);
}
//功能:重载赋值运算=
//前置:NULL;调用destroylist();
template<class T>
const linkdlist<T>& linkdlist<T>::operator=(const linkdlist<T>& otherlist)
{
if(this!=&otherlist)
copylist(otherlist);
return *this;
}
template<class T>
void linkdlist<T>::print()
{
nodetype<T> *current;
current=first;
while(current!=NULL)
{
cout<<"current->info="<<current->info<<"/n";
current=current->link;
}
cout<<"/n length="<<count;
}
//end all code
//test file main.cpp
#include <iostream>
#include <iomanip>
#include <cassert>
#include <fstream>
#include <ostream>
using namespace std;
#include "linkdlist.h"
int main()
{
linkdlist<int> list1,list2;
cout<<"****链表类模板测试***/n";
int x=888;
list1.initlist();
list1.insertfirst(x);
list1.insertlast(999);
cout<<"list1.insertfirst(x)/n";
list1.print();
list2=list1;
cout<<"list2=list1/n";
list2.print();
cout<<"destroylist()/n";
list2.destroylist();
list2.print();
cout<<"/n";
return 0;
}
//谁的时间多就用main做一个比较全面的测试
List C++链式线性表模板
最新推荐文章于 2024-06-04 11:26:12 发布