集合的无序链表实现

template<class T>
struct SetNode{
    T data;
    SetNode<T> *link;
    SetNode<T>(){link = NULL;}
    SetNode<T>(T &item){data = item;link = NULL;}
};
template<class T>
class Set{                                       //带头结点的结合的链表实现
private:
    SetNode<T> *first;
    int length;
public:
    Set(){first = new SetNode<T>();length = 0;}
    ~Set(){MakeEmpty();delete first;}
    void MakeEmpty();                            //置空集合
    int AddMember(T x);                          //增加x到集合中,成功返回1,不成功返回-1
    int DelMember(T &x);                         //删除集合中的元素x,成功返回1,不成功返回-1
    Set<T>& operator=(Set<T> &right);            //复制集合right到this
    Set<T> operator+(Set<T> &right);             //求集合this与right的并集
    Set<T> operator*(Set<T> &right);             //求集合this与right的交集
    Set<T> operator-(Set<T> &right);             //求集合this与rihgt的差集
    int Contains(T x);                           //判断x是否是集合的成员
    int operator==(Set<T> &right);               //判断集合是否相等
    SetNode<T> *Min();                           //返回集合中最小的元素
    SetNode<T> *getFirst(){return first;}        //返回头节点
    bool isEmpty(){return first->link == NULL;}  //判断集合是否为空
    int getLength(){return length;}
    void output(){
        SetNode<T> *temp = first->link;
        while(temp != NULL){
            cout << temp->data << " ";
            temp = temp->link;
        }
        cout << endl;
    }
};

template<class T>
void Set<T>::MakeEmpty(){                        //递归删除链表的节点来置空集合
    SetNode<T> *p = first,*q = p->link;
    while(q != NULL){
        p->link = q->link;
        cout << "删除" << q->data << " ";
        delete q;
        q = p->link;
    }
    p->link = NULL;
    length = 0;
}

template<class T>
int Set<T>::AddMember(T x){                      //将新节点插入到链表最后
    SetNode<T> *p = first;
    while(p->link != NULL){
        if(p->data == x)break;
        p = p->link;
    }
    if(p->data == x)return -1;                   //元素x已经在集合中存在所以增加元素失败
    SetNode<T> *add = new SetNode<T>(x);
    if(add == NULL)return -1;
    p->link = add;
    length++;
    return 1;
}
template<class T> 
int Set<T>::DelMember(T &x){                     //删除集合中的元素x               
    if(isEmpty())return -1;
    SetNode<T> *p = first,*q = p->link;
    while(q != NULL){
        if(q->data == x)break;
        q = q->link;
        p = p->link;
    }
    if(q == NULL)return -1;
    SetNode<T> *del = q;
    p->link = del->link;
    delete del;
    length--;
    return 1;
}

template<class T>
Set<T>& Set<T>::operator=(Set<T> &right){         //复制构造函数
    if(right.isEmpty()){
        MakeEmpty();return *this;
    }
    MakeEmpty();
    SetNode<T> *p = right.getFirst()->link;
    SetNode<T> *p1 = first;
    while(p != NULL){
        p1->link = new SetNode<T>(p->data);
        p1 = p1->link;
        p = p->link;
    }
    length = right.getLength();
    return *this;
}
template<class T>
Set<T> Set<T>::operator+(Set<T> &right){
    Set<T> Union;
    if(right.isEmpty()){Union = *this;return Union;}
    Union = right;
    SetNode<T> *p = first->link,*q,*r,*m;
    while(p != NULL){                    //从头开始遍历集合一
        q = Union.getFirst()->link;
        while(q != NULL){                //在集合二中查找是否存在集合一中的元素
            if(q->data == p->data)break; 
            q = q->link;
        }
        if(q == NULL){                   //若不存在,将集合一中该元素插入到集合二中
            r = Union.getFirst();
            while(r->link != NULL)r = r->link;
            m = new SetNode<T>(p->data);
            r->link = m;
        }
        p = p->link;
    }
    Union.length = length + right.getLength();
    return Union;
}

template<class T>
Set<T> Set<T>::operator*(Set<T> &right){
    Set<T> intersection; int l = 0;
    if(right.isEmpty()){cerr << "与空集无交集" << endl;return intersection;}
    SetNode<T> *p,*q;
    p = first->link;
    while(p != NULL){                     //遍历集合一
        q = right.getFirst()->link;
        while(q != NULL){
            if(q->data == p->data)break;  //在集合二中查找集合一中元素是否存在
            q = q->link;
        }
        if(q != NULL){                    //不存在就插入交集集合
            intersection.AddMember(q->data);
            l++;
        }
        p = p->link;
    }
    intersection.length = l;
    return intersection;
}
template<class T>
Set<T> Set<T>::operator-(Set<T> &right){          //求与right集合的差集,right是子集
    Set<T> difference;int l = 0;
    if(right.isEmpty()){difference = *this;return difference;}
    if(right.length > length){cerr << "子集大于总集" << endl;return difference;}
    SetNode<T> *p,*q,*r;
    p = first->link;
    q = right.getFirst()->link;
    //先检查是否总集包含子集
    while(p != NULL){
        q = right.getFirst()->link;
        while(q != NULL){
            if(q->data != p->data)break;
            q = q->link;
        }
        if(q != NULL){
            cerr << "求差集的时候存在元素在子集但不在总集" << endl;difference.MakeEmpty();return difference;
        }
        p = p->link;
    }
    p = first->link;q = right.getFirst()->link;
    while(q != NULL){
        while(p != NULL){
            if(q->data == p->data)break;
            p = p->link;
        }
        if(p == NULL){difference.AddMember(p->data);l++;}
        q = q->link;
    }
    difference.length = l;
    return difference;
}
template<class T>
int Set<T>::Contains(T x){
    SetNode<T> *p = first->link;
    while(p != NULL){
        if(p->data == x)break;
        p = p->link;
    }
    if(p == NULL)return -1;
    return 1;
}
template<class T>
int Set<T>::operator==(Set<T> &right){
    if(length != right.getLength())return -1;
    SetNode<T> *p,*q;
    p = first->link;
    q = right.getFirst()->link;
    while(p != NULL){
        while(q != NULL){
            if(p->data != q->data)break;
            q = q->link;
        }
        if(q == NULL)
            p = p->link;
        else
            return -1;
    }
    return 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值