单链表实现集合的并、交、差运算

数据结构课程笔记 专栏收录该内容
5 篇文章 0 订阅

带头结点的单链表实现集合的并、交、差运算。

#include <iostream>  //引用输入输出流库函数的头文件
using namespace std;
template <class T>
struct Node
{
  T data;
  Node<T> *next;  //此处<T>也可以省略
};

template <class T>
class LinkList
{
  public:
    LinkList( );  //建立只有头结点的空链表
    LinkList(T a[ ], int n);  //建立有n个元素的单链表
    ~LinkList();             //析构函数
    int Length();          //求单链表的长度
    T Get(int i);           //取单链表中第i个结点的元素值
    int Locate(T x);       //求单链表中值为x的元素序号
    void Insert(int i, T x);   //在单链表中第i个位置插入元素值为x的结点
    T Delete(int i);        //在单链表中删除第i个结点
    void PrintList( );           //遍历单链表,按序号依次输出各元素
 private:
   Node<T> *first;  //单链表的头指针
};
/*
*前置条件:单链表不存在
*输    入:无
*功    能:构建一个单链表
*输    出:无
*后置条件:构建一个单链表
*/
template <class T>
LinkList<T>:: LinkList( )
{
 first=new Node<T>; first->next=NULL;
}
/*
*前置条件:单链表不存在
*输    入:顺序表信息的数组形式a[],单链表长度n
*功    能:将数组a[]中元素建为长度为n的单链表
*输    出:无
*后置条件:构建一个单链表
*/

template <class T>
LinkList<T>:: LinkList(T a[ ], int n)
 {
    first=new Node<T>;   //生成头结点
    Node<T> *r,*s;
     r=first;          //尾指针初始化
    for (int i=0; i<n; i++)
    {
      s=new Node<T>; s->data=a[i];  //为每个数组元素建立一个结点
      r->next=s; r=s;      //插入到终端结点之后
    }
    r->next=NULL;    //单链表建立完毕,将终端结点的指针域置空
 }


/*
*前置条件:无
*输    入:无
*功    能:无
*输    出:无
*后置条件:无
*/
template <class T>
LinkList<T>::~LinkList()
 {
     cout<<"~LinkList()"<<Length()<<endl;

      Node<T> *q;
     while(first!=NULL)
     {
         q=first;//cout<<q->data<<endl;
         first=first->next;
         delete q;
     }
 }
/*
*前置条件:单链表存在
*输    入:查询元素位置i
*功    能:按位查找位置为i的元素并输出值
*输    出:查询元素的值
*后置条件:单链表不变
*/
template <class T>
T LinkList<T>::Get(int i)
{
  Node<T> *p; int j;
  p=first->next;  j=1;  //或p=first;  j=0;
  while (p && j<i)
  {
    p=p->next;       //工作指针p后移
    j++;
  }
  if (!p) throw "位置";
  else return p->data;
}

/*
*前置条件:单链表存在
*输    入:查询元素值x
*功    能:按值查找值的元素并输出位置
*输    出:查询元素的位置
*后置条件:单链表不变
*/
template <class T>
int LinkList<T>::Locate(T x)
{
    Node<T> *p; int j;
    p=first->next; j=1;
    while (p){
      if(p->data==x)    return j;
      else
      {
         p=p->next;
         j++;
      }
    }
    return 0;
}

/*
*前置条件:单链表存在
*输    入:插入元素x,插入位置i
*功    能:将元素x插入到单链表中位置i处
*输    出:无
*后置条件:单链表插入新元素
*/
template <class T>
void LinkList<T>::Insert(int i, T x)
{
   Node<T> *p; int j;
   p=first ; j=0;    //工作指针p初始化
   while (p && j<i-1)
   {
     p=p->next;   //工作指针p后移
     j++;
   }
   if (!p) throw "位置";
    else {
      Node<T> *s;
      s=new Node<T>;
      s->data=x;  //向内存申请一个结点s,其数据域为x
      s->next=p->next;       //将结点s插入到结点p之后
      p->next=s;
    }
}

/*
*前置条件:单链表存在
*输    入:无
*功    能:输出单链表长度
*输    出:单链表长度
*后置条件:单链表不变
*/
template <class T>
int LinkList<T>::Length( )
{
  Node <T> *p = first->next;
  int i = 0;
  while(p)
  {
    p = p->next;
    i++;
  }
  return i;
}
/*
*前置条件:单链表存在
*输    入:要删除元素位置i
*功    能:删除单链表中位置为i的元素
*输    出:无
*后置条件:单链表删除元素
*/
template <class T>
T LinkList<T>::Delete(int i)
{
  Node<T> *p; int j;
  p=first ; j=0;  //工作指针p初始化
  while (p && j<i-1)  //查找第i-1个结点
  {
    p=p->next;
    j++;
  }
  if (!p || !p->next) throw "位置";  //结点p不存在或结点p的后继结点不存在
    else {
          Node<T> *q; int x;
          q=p->next; x=q->data;  //暂存被删结点
          p->next=q->next;  //摘链
          delete q;
          return x;
    }
}
/*
*前置条件:单链表存在
*输    入:无
*功    能:单链表遍历
*输    出:输出所有元素
*后置条件:单链表不变
*/
template <class T>
void LinkList<T>::PrintList( )
{
    Node<T> *p;
    p=first->next;
    while (p)
    {
      cout<<p->data<<" ";
      p=p->next;
    }
    cout<<endl;
}
//LinkListMain.cpp
template <typename T>
void Unionset(LinkList <T> &a,LinkList <T> &b){//right
    //改变了a
    T temp;
    for(int i=1;i<=b.Length();i++)
    {
        temp=b.Get(i);
        if(!a.Locate(temp))a.Insert(a.Length()+1,temp);
    }
}
template <typename T>
void Unionset1(LinkList <T> a,LinkList <T> b){
    //wrong: _CrtIsValidHeapPointer
    //因为函数返回时a,b被析构
    T temp;
    for(int i=1;i<=b.Length();i++)
    {
        temp=b.Get(i);
        if(!a.Locate(temp))a.Insert(a.Length()+1,temp);
    }
}
template <typename T>
LinkList <T> Unionset2(LinkList <T> a,LinkList <T> b){
    //wrong: _CrtIsValidHeapPointer
    //因为函数返回时a,b被析构
    T temp;
    for(int i=1;i<=b.Length();i++)
    {
        temp=b.Get(i);
        if(!a.Locate(temp))a.Insert(a.Length()+1,temp);
    }
    return a;
}
 template <typename T>
void UnionSet(LinkList<T>&C,LinkList<T>&A,LinkList<T>&B)
//A∪B=C
{
    //LinkList<T> C;
    T temp;
    int i;
    for(i=1;i<=A.Length();i++)
    {
        temp=A.Get(i);
        C.Insert(C.Length()+1,temp);
    }
    for(i=1;i<=B.Length();i++)
    {
        temp=B.Get(i);
        if(!A.Locate(temp))C.Insert(C.Length()+1,temp);
    }
    //return C;

}
template <typename T>
void IntersectionSet(LinkList<T>&C,LinkList<T>&A,LinkList<T>&B)
//A∩B=C
 {
     //LinkList<T> C;
    T temp;
    int i;

    for(i=1;i<=B.Length();i++)
    {
        temp=B.Get(i);
        if(A.Locate(temp))C.Insert(C.Length()+1,temp);
    }
    //return C;
 }
 template <typename T>
void IntersectionSet1(LinkList<T>&A,LinkList<T>&B)
//A∩B=A
 {
     //LinkList<T> C;
    T temp;
    int i;

    for(i=1;i<=A.Length();i++)
    {
        temp=A.Get(i);
        if(B.Locate(temp)==0){A.Delete(i);i--;}
    }
    //return C;
 }
 template <typename T>
void  DifferenceSet(LinkList<T>&C,LinkList<T>&A,LinkList<T>&B)
//A-B=c
 {
    //LinkList<T> C;
    T temp;
    int i;

    for(i=1;i<=A.Length();i++)
    {
        temp=A.Get(i);
        C.Insert(C.Length()+1,temp);
    }
    for(i=1;i<=B.Length();i++)
    {
        temp=B.Get(i);
        if(A.Locate(temp)!=0){
            int pos=C.Locate(temp);
            C.Delete(pos);}
    }
    //return C;
 }
int main( )
{
    int ra[ ]={1,2,3,4,5};
    LinkList <int> A(ra,5);     //根据数组创建单链表
    cout<<"链表A中的元素为:"<<endl;
    A.PrintList();            //输出单链表a所有元素
    int rb[ ]={2,0,9,3,5};
    LinkList <int> B(rb,5);     //根据数组创建单链表
    cout<<"链表B中的元素为:"<<endl;
    B.PrintList();

    //UnionSet(a,b);
    //UnionSet1(a,b);
    //a=UnionSet2(a,b);
    //cout<<"链表a中的元素为:"<<endl;
    //a.PrintList();            //输出单链表a所有元素
    //b.PrintList();
    LinkList<int>C;
     UnionSet(C,A,B);
     cout<<"A∪B=";C.PrintList();
     LinkList<int>D;
     IntersectionSet(D,A,B);
     cout<<"A∩B=";D.PrintList();
     LinkList<int>E;
     DifferenceSet(E,A,B);
     cout<<"A-B=";E.PrintList();
     IntersectionSet1(A,B);
     cout<<"A∩B=";A.PrintList();
     return 0;
}


 

  • 10
    点赞
  • 0
    评论
  • 48
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值