数据结构之Chain类

来源:互联网 发布:php erp系统 编辑:程序博客网 时间:2024/04/26 04:09
//基于链表的类Chain#include <iostream>using namespace std;//节点类,定义了每个节点的存储类型和指针名称template<class T>class ChainNode{public:    T data;    ChainNode<T> *link;};//链表类,封装了链表操作的相应方法template<class T>class Chain{public:    Chain()    {        first=0;    //构造函数,头结点指向空值    }    ~Chain();//析构函数    bool IsEmpty()const    {        return first==0;    //判断是否为空    }    int Length()const;//返回该链表的长度    bool Find(int k,T&x)const;//返回第k个元素到x中    int Search(const T&x)const;//返回x所在的位置    Chain<T>& Delete(int k,T& x);//删除第k个元素并把它返回到x中    Chain<T>& Insert(int k,const T&x);//在第k个元素之后插入x    void Output(ostream& out) const;//重载操作符的输出函数    ChainNode<T> *first;//指向第一个节点的指针    ChainNode<T> *last;//指向最后一个节点的指针    void Erase();    void Zero()    {        first=0;    };    Chain<T>& Append(const T&x);};//链表遍历器类实现对链表的遍历template<class T>class ChainIterator{public:    T* Initialize(const Chain<T>&c)    {        location = c.first;        if(location)        {            return &location->data;//为何有地址符?        }        return 0;    }    T* Next()    {        if(!location)            return 0;        location = location->link;        if(location)            return &location->data;        return 0;    }private:    ChainNode<T>*location;};//链表的析构函数,用于删除所有的链表中的节点template<class T>Chain<T>::~Chain(){    Erase();}//清除掉链表中的所有元素并且释放内存template<class T>void Chain<T>::Erase(){    ChainNode<T>*next;    //指向下一个节点    while(first)    {        next=first->link;        delete first;        first = next;    }}//输出链表template<class T>void Chain<T>::Output(ostream& out)const{    ChainNode<T>*current;    for(current=first; current; current=current->link)    {        out<<current->data;        if(!current->link)        {            out<<""<<endl;        }        else        {            out<<",";        }    }}//重载操作符template<class T>ostream& operator<<(ostream& out,const Chain<T>&x){    x.Output(out);    return out;}class OutOfBounds{public:    OutOfBounds()    {        cout<<"Out Of Bounds!"<<endl;    }};//内存不足的异常类class NoMem{public:    NoMem()    {        cout<<"No Memory!"<<endl;    }};//使new引发NoMem异常而不是xalloc异常//如果要恢复原始行为可以做以下调用//_set_new_handler(Old_Handler);int my_new_handler(size_t size){    throw NoMem();}//确认链表的长度template<class T>int Chain<T>::Length()const{    ChainNode<T>*current = first;    int length = 0;    while(current)    {        length++;        current = current->link;    }    return length;}//在链表中查找第k个元素//存在就储存到x中//不存在则返回false,否则返回truetemplate<class T>bool Chain<T>::Find(int k,T&x)const{    if(k<1)        return false;    ChainNode<T>*current = first;    int index = 1;    while(index<k&¤t)    {        current = current->link;        index++;    }    if(current)    {        x = current->data;        return true;    }    return false;}//在链表中搜索//查找x,如果发现则返回x的下标//如果x不存在则返回0template<class T>int Chain<T>::Search(const T&x)const{    ChainNode<T>*current = first;    int index = 1;    while(current&¤t->data!=x)    {        current = current->link;        index++;    }    if(current)    {        return index;    }    return 0;}//从链表中删除一个元素//将第k个元素取至x//然后从链表中删除第k个元素//如果不存在则引发异常OutOfBoundstemplate<class T>Chain<T>& Chain<T>::Delete(int k,T& x){    if(k<1||!first)    {        throw OutOfBounds();    }    ChainNode<T>*p = first;    if(k==1)    {        first = first->link;    }    else    {        ChainNode<T>*q = first;        for(int index = 1; index<k-1&&q; index++)        {            q = q->link;            //此时q指向要删除的前一个节点        }        if(!q||!q->link)        {            throw OutOfBounds();        }        p = q->link;        if(p==last)            last=q;        q->link=p->link;        //从链表中删除该节点        x = p->data;        delete p;        return *this;    }}//在第k个位置之后插入元素//不存在则报OutOfBounds异常//没有足够内存则报NoMem异常template<class T>Chain<T>& Chain<T>::Insert(int k,const T&x){    if(k<0)    {        throw OutOfBounds();    }    ChainNode<T>*p = first;    for(int index = 1; index<k && p; index++)    {        p = p->link;    }    if(k>0 && !p)    {        throw OutOfBounds();    }    ChainNode<T>*y = new ChainNode<T>;    y->data = x;    if(k)    {        y->link=p->link;        p->link=y;    }    else    {        //作为第一个元素插入        y->link = first;        first = y;    }    if(!y->link)        last=y;    return *this;}//在链表右端添加一个数据template<class T>Chain<T>& Chain<T>::Append(const T&x){    ChainNode<T>*y;    y = new ChainNode<T>;    y->data = x;    y->link = 0;    if(first)    {        last->link = y;        last = y;    }    else    {        first = last = y;    }    return *this;}int main(){    Chain<int>myList;    cout<<"myList : "<<myList<<endl;    cout<<"Length  = "<<myList.Length()<<endl;    cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;    myList.Append(5);    myList.Append(0);    myList.Insert(1,2);    cout<<"myList : "<<myList<<endl;    cout<<"Length  = "<<myList.Length()<<endl;    cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;    int f ;    myList.Find(1,f);//把第一个位置的元素赋值给z了    cout<<"First is "<<f<<endl;    cout<<"Length  = "<<myList.Length()<<endl;    myList.Delete(1,f);    cout<<"Delete is "<<f<<endl;    cout<<"myList : "<<myList<<endl;    cout<<"Length  = "<<myList.Length()<<endl;    cout<<"IsEmpty = "<<myList.IsEmpty()<<endl;    cout<<"Iterator : "<<endl;    //使用遍历器输出    int *x;    ChainIterator<int>c;    x=c.Initialize(myList);    while(x)    {        cout<<*x;        x = c.Next();        if(x)        {            cout<<",";        }        else        {            cout<<""<<endl;        }    }    cout<<endl;return 0;}

0 0