[C++]数据结构实验03:链式结构线性表的基本操作

/**********************************************************************************************************************************/
/*	实验三:线性表操作
/*	1.创建线性表类。线性表的存储结构使用链表。
/*	2.完成表首插入元素、删除指定元素、搜索表中是否有指定元素、输出链表。
/*	3.输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建链表。输出整个链表。
/*	4.输入一个整数,将该数作为一个元素值插入表首位置。输出整个链表。
/*	5.输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
/*	6.再一次输入一个整数,在链表中进行搜索,输出其在链表中的位置。如果不存在输出0。
/*	7.使用链表遍历器实现链表的反序输出。
/*	8.再一次输入n个不为零的整数作为节点元素值,遇到0代表输入结束(不创建元素值为0的节点),创建另外一个链表,输出整个链表。
/*	9.使用链表遍历器实现上面两个链表的合并,输出合并后的链表。
/**********************************************************************************************************************************/


#include <iostream>
#include<new.h>
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,否则返回true
template<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&& current){
        current = current->link;
        index++;
    }
    if(current){
        x = current->data;
        return true;
    }
    return false;
}


//在链表中搜索
//查找x,如果发现则返回x的下标
//如果x不存在则返回0
template<class T>
int Chain<T>::Search(const T&x)const{
    ChainNode<T>*current = first;
    int index = 1;
    while(current&& current->data!=x){
        current = current->link;
        index++;
    }
    if(current){
        return index;
    }
    return 0;
}



//从链表中删除一个元素
//将第k个元素取至x
//然后从链表中删除第k个元素
//如果不存在则引发异常OutOfBounds
template<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()
{
    int count = 0;

    //收集输入的内容至链表a当中
    Chain<int> a;
	
    cout<<"Input1"<<endl;
    while(true)
    {
        int b;
        cin>>b;
        if(b==0)break;
        a.Append(b);
        count++;
    }
	
    cout<<"Output1"<<endl;
    cout<<a<<endl;
	
    cout<<"Input2"<<endl;
    int c1;
    cin>>c1;
    a.Insert(0,c1);
    count++;
    cout<<"Output2"<<endl;
    cout<<a<<endl;
	
	
    cout<<"Input3"<<endl;
    int q;
    cin>>q;
    cout<<"Output3"<<endl;
    cout<<a.Search(q)<<endl;
	
    cout<<"Input4"<<endl;
    int q2;
    cin>>q2;
    cout<<"Output4"<<endl;
    cout<<a.Search(q2)<<endl;
	
    Chain<int> w;
    count = 0;
    cout<<"Input5"<<endl;
	
    while(true){
        int b;
        cin>>b;
        if(b==0)break;
        w.Append(b);
        count++;
    }
	
    //直接将w链表遍历加在a链表的尾部
    cout<<"Output5"<<endl;
    ChainNode<int>*current = w.first;
    while (current)
    {
        a.Append(current->data);
        current= current->link;
    }
    cout<<a<<endl;
    return 0;
}


你可能感兴趣的:([C++]数据结构实验03:链式结构线性表的基本操作)