List C++链式线性表模板

来源:互联网 发布:室内平面图软件 编辑:程序博客网 时间:2024/05/21 09:24

  链表的模板实现,我在上面有非常详细的标注
/*
链表和数组是一个非常重要的数据结构,常用于实现队列,堆栈,二叉树等数据结构
所以请大家一定要掌握链表和数据的特性
实现方式:在一个头文件中以完整的方式
实现链表模板
链表功能:
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做一个比较全面的测试

原创粉丝点击