求交集 并集 与差集 单链表实现

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define null 0
#define M 100
/*定义链表*/
typedef int ElemType;
typedef struct Lnode
{
    ElemType data;
    struct Lnode *next;
}Lnode,*LinkList;


int lenth(LinkList *L)/*返回链表长度*/
{
    int n = 0;
    LinkList t;
   
 t = (*L);   //这里要注意一下 仔细想想就OK了
    while (t != null)
    {
           n++;
           t = t->next;
    }
        return n;
}

ElemType get(LinkList *L,int n)/*返回指定节点的值*/
{
      int i = 1;
      LinkList t;
    
   t = *L;
      while (i < n && t != null)
   {
          t = t->next;
          i++;
   }
      if (t != null)
   {
        return(t->data);
      }
      else
   {
        printf("The %dth Lnode haven't find !/n",n);
        return 0;
   }
}

int locate(LinkList *L,ElemType x )/*定位指定值的节点的位置*/
{
     int n = 1;
     LinkList t;
    
  t = *L;
     while (t != null && t->data != x)
  {
          t = t->next;
          n++;
  }
     if(t == null)
  {
        return 0;
     }
     else
     {
        return n;
     }
}

void display(LinkList *L)/*显示链表*/
{
    LinkList t;
   
 t=*L;
    if (t == null)//这句可以不要 
    {
        printf("The link is null!");
    }
    else
    {
        do
          {
            printf("%d>>",t->data);
            t = t->next;
    }while(t != null);
    }
    printf("/n");
}


void creat(LinkList *L)/*无头节点      创建链表,并设置链表为空*/
{
    *L = null;
}

void insert(LinkList *L,int n,ElemType x)/*向链表中插入元素*/
{
    /*插在第n个节点的前面*/
    LinkList t1,t2;
    int j = 1;
   
 t1 = (struct Lnode *)malloc(sizeof(struct Lnode));
    t1->data = x;
    t2 = *L;
    if (n == 1)
    {
       t1->next = t2; //无头节点
       *L = t1;
    }
    else
    {
        while (j < n-1 && t2->next!=null)
        {
            t2 = t2->next;
            j++;
        }
        if (j == n-1)
        {
           t1->next = t2->next;
           t2->next = t1;
        }
        else
        {
           printf("Insert error!");//这里处理的比较好
        }
    }
}

void delete(LinkList *L,int n)/*删除指定位置的节点*/
{
    int i = 1;
    LinkList t1, t2;
  
    t1 = *L;
    if (n == 1)
    {
        t2 = t1;
        *L = t1->next;
    }
    else
    {
        while (i < n-1 && t1->next != null)
  {
            t1 = t1->next;
            i++;
  }
        if (t1->next != null && i == n-1)
        {
            t2 = t1->next;
            t1->next = t2->next;
        }
        else
  {
             printf("Delete error!/n");
        }
    }
    if (t2 == null)
 {
       free(t2);
    }
}

void init(struct Lnode **L,int len)/*初始化链表  这个函数体觉得很臃肿*/
{
    int d[M],i,j,k,ti;
//  struct Lnode *t;
input:
    for (i = 1; i <= len; i++)
    {
       scanf("%d",&d[i]);
    }
    for(j = 1; j <= len; j++)
      for(k = j+1; k <= len; k++)
      {
         if (d[j] > d[k])
         {
             ti = d[j];
             d[j] = d[k];
             d[k] = ti;
         }
      }
    for (i = 1; i < len; i++)
    {
         if (d[i] == d[i+1])
         {
           printf("Don't allow the same data! Please reinput!");
           goto input;
         }
    }
    creat(&*L);
    for (i = 1; i <= len; i++)
    {
         insert(&*L, i, d[i]);
    }
    printf("The data of the linktable is:  ");
    display(&*L);
   
}

void copy(struct Lnode **L1,struct Lnode **L2 )/*复制链表L1到L2*/
{

  int i,len;
  ElemType t;
 
  len = lenth(&*L1);
  creat(&*L2);
  for (i = 1; i <= len; i++)//取L1中的元素依次插入L2中
  {
      t = get(&*L1,i);
      insert(&*L2,i,t);
  }
}

void intersection(struct Lnode **L1,struct Lnode **L2,struct Lnode **L3)/*求交集*/
{   
    
     int i, j, k = 1;
     struct Lnode *t1,*t2;
     t1 = *L1;
     t2 = *L2;
     creat(&*L3);
     for(i = 1; i <= lenth(&*L1); i++)
     {
       for(j = 1; j <= lenth(&*L2); j++)
       {
          if(t1->data == t2->data)
          {
              insert(&*L3, k, t1->data);
              k++;
          }
          t2 = t2->next;
        }
        t1 = t1->next;
        t2 = *L2;
     }

}

unionset(struct Lnode **L1,struct Lnode **L2,struct Lnode **L3)/*求并集*/
{/*把L1复制到L3,然后比较L2与L3,得到L2在L3中没有的元素在L3中的位置,并插入*/
  int i,j,k;
  struct Lnode *tt,*t2,*t3;
 
  creat(&*L3);
  copy(&*L1,&*L3);
  t2 = *L2;
  t3 = *L3;
  for (i = 1; i <= lenth(&*L2); i++)
  {
      k = 1;
      for (j = 1; j <= lenth(&*L3); j++)
      {
          if (t2->data == t3->data)
          {
              k = 0;
              break;
          }
          else if(t2->data < t3->data)
          {
             break;
          }
          else if(t2->data > t3->data)
          {
             k++;
             if(k <= lenth(&*L3))
             {
               t3 = t3->next; // 还是有点不懂
             }
           }
        }
       if (k > 0 && k <= lenth(&*L3))/*插在排序的位置上*/
       {
          insert(&*L3,k,t2->data);
       }
       else if(k > lenth(&*L3))/*插在链尾*/
       {
         tt = (struct Lnode *)malloc(sizeof(struct Lnode));
         tt->data = t2->data;
         tt->next = null;
         t3->next = tt;
       }
       t2 = t2->next;
       t3 = *L3;
      }
}

void diffrenceset(struct Lnode **L1,struct Lnode **L2,struct Lnode **L3)/*求差集*/
{
/*将第一个复制到第三个,查找第二个在第三个中有的元素,并确定它在第三个中的位置,然后从第三个中删除*/
  int i,t,n;
 
  creat(&*L3);
  copy(&*L1,&*L3);
  for (i = 1; i <= lenth(&*L2); i++)
  {
      t = get(&*L2,i);
      n = locate(&*L3,t);
      if (n)
      {
         delete(&*L3, n);
      }
  }
}
int main(void)
{
  int len1,len2;

  static struct Lnode *head1,*head2,*head3,*head4,*head5,*head6;
  printf("/************************************************************************//n");
  printf("Please input the lenth of the first linktable!  ");
  scanf("%d",&len1);
  printf("/************************************************************************//n");
  printf("The lenth of the first linktable is %d,please input %d int data!  ",len1,len1);
  init(&head1,len1);
  printf("/************************************************************************//n");
  printf("Please input the lenth of the second linktable!  ");
  scanf("%d",&len2);
  printf("/************************************************************************//n");
  printf("The lenth of the second linktable is %d,please input %d int data!  ",len2,len2);
  init(&head2,len2);
  printf("/n/n/-----------------------------fire works---------------------------------//n");
  intersection(&head1,&head2,&head3);
  printf("The intersection of two linktable:  ");
  display(&head3);
  printf("/-----------------------------fire works---------------------------------//n");
  unionset(&head1,&head2,&head4);
  printf("The union set of two linktable:  ");
  display(&head4);
  printf("/-----------------------------fire works---------------------------------//n");
  diffrenceset(&head1,&head2,&head5);/*第一个减第二个的差集*/
  printf("The set of the first-second:  ");
  display(&head5);
  diffrenceset(&head2,&head1,&head6);/*第二个减第一个的差集*/
  printf("The set of the second-first:  ");
  display(&head6);
  printf("/-----------------------------fire works---------------------------------//n");
 
  system("pause");
  return 0;
 
}  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值