链表求交集、并集和差集

这篇博客介绍了如何使用C语言创建链表,并实现两个链表的交集、并集和差集的计算。提供了有序和无序集合的交集算法,以及直接修改原链表的差集操作和新建链表存储差集的方法。此外,还包括了链表的插入、查找和删除功能。
摘要由CSDN通过智能技术生成

链表求交集、并集和差集

C语言建立链表,输入集合A和集合B,求集合A和B的交集、并集和差集;
求交集写了两种,一种是求两个非递减集合的交集,另一种是无序集合

以下是打代码块

#include <stdio.h>
#include <stdlib.h>


int ans;
typedef struct Lnode{

    int data;
    struct Lnode *next;
}Lnode,*LinkList;



//链表初始化
LinkList InitList(LinkList L,int n){
    int data;
    L = (LinkList)malloc(sizeof(Lnode));
    //建立头结点
    L->next = NULL;
    //定义一个head指向L的头部
    LinkList head = L;

    for(int i = 0;i < n;i++){
        LinkList p = (LinkList)malloc(sizeof(Lnode));
        scanf("%d",&data);
        p->data = data;
        p->next = L->next;
        L->next = p;
        L=L->next;
    }

    return head;
}



//插入数据
LinkList InsertList(LinkList L,int i,int data){

    LinkList head = L;
    //标记插入的位置
    int mark = 1;
    while(L){
        if(mark == i){
            LinkList p = (LinkList)malloc(sizeof(Lnode));
            p->data = data;
            p->next = L->next;
            L->next = p;
            free(p);
            break;
        }
        mark++;
        L = L->next;
    }

    return head;
}

//求交集(有序)
LinkList Intersection(LinkList L1,LinkList L2){
    //存放交集C
    LinkList L3 = (LinkList)malloc(sizeof(Lnode));
    //初始化一下;
    L3->next = NULL;
    //标记C集合的头结点;
    LinkList head = L3;
    //用来替换L1,L2;
    LinkList p = L1->next,q= L2->next;
    //如果一个为空,跳出循环;
    while(p&&q){
            //如果相等,存入集合C
        if(p->data == q->data){
            LinkList tmp = (LinkList)malloc(sizeof(Lnode));
            tmp ->data = p->data;
            tmp->next = L3->next;
            L3->next = tmp;
            L3 = L3->next;
            p = p->next;
            q = q->next;
            continue;
        }
        //链表是递增顺序,如果集合A的数值小于集合B的数值,集合A往后移动一位,
        if(p->data > q->data){
            q = q->next;
        }
        //反之,移动集合B
        if(p->data < q->data){
            p = p->next;
        }
    }
    //返回标记的头;
    return head;
}
//查找数值
int Searchvalue(LinkList L,int data){
    LinkList head = L->next;
    while(head){
        if(head->data == data){
            return 1;
        }
        head = head->next;
    }
    return 0;

}
//删除链表的值
LinkList DeleteList(LinkList L,int data){
    LinkList head = L;
    while(L){
        if(L->next!=NULL&&L->next->data == data){
            L->next = L->next->next;
            break;
        }
        L = L->next;
    }
    return head;

}

//求交集(无序集合)
LinkList Intersection01(LinkList L1,LinkList L2){
    LinkList q = L1, p = L2;
    LinkList L = (LinkList)malloc(sizeof(Lnode));
    L ->next = NULL;
    LinkList head = L;
    while(q){
        if(Searchvalue(L2,q->data)){
            LinkList tmp = (LinkList)malloc(sizeof(Lnode));
            tmp ->data = q->data;
            tmp->next = L->next;
            L->next = tmp;
            L = L->next;
        }
        q = q->next;
    }
    return head;
}


//求差集(直接对L1进行操作)
void differentSet(LinkList L1,LinkList L2){
    //指向L1,L2
    LinkList p = L1->next,q = L2->next;
    //循环L2;
    while(q){
            //在L1中查找L2的值,如果相等,就在L1中删除该值
        if(Searchvalue(L1,q->data)){
            L1 = DeleteList(L1,q->data);
        }
        q = q->next;
    }
}
//求差集(零件一个链表储存)
LinkList differentSet01(LinkList L1,LinkList L2){
    //建立集合C储存差集
    LinkList L = (LinkList)malloc (sizeof(Lnode));
    L ->next = NULL;
    LinkList head = L;
    //替换L1,L2,防止两个链表被破坏
    LinkList p = L1->next,q = L2->next;
    //循环L2;
    while(p){
            //在L1中查找L2的值,如果相等,就在L1中删除该值
        if(!Searchvalue(L2,p->data)){
            LinkList tmp = (LinkList)malloc(sizeof(Lnode));
            tmp ->data = p->data;
            tmp->next = L->next;
            L->next = tmp;
            L = L->next;
        }
        p = p->next;
    }
    return head;
}

//求并集
LinkList Unionset(LinkList L1,LinkList L2){

    //替换L1,L2;
    LinkList p = L1->next,q = L2->next;
    //集合C存并集
    LinkList uni = (LinkList)malloc(sizeof(Lnode));
    uni->next = NULL;

    LinkList head_un = uni;

    ans = ans+1;
    while(p){
        LinkList tmp = (LinkList)malloc(sizeof(Lnode));
        tmp->data = p->data;
        tmp->next = uni->next;
        uni->next = tmp;
        p = p->next;
        uni = uni->next;
    }
    while(q){
        if(!Searchvalue(L1,q->data)){
            InsertList(head_un,ans,q->data);
            ans ++;
        }
        q = q->next;
    }
    return head_un;

}

//输出链表
void printList(LinkList L){

    LinkList head = L->next;
    while(head){
        printf("%d ",head->data);
        head=head->next;
    }
    printf("\n");
}


int main()
{
    LinkList L1,L2;

    int n;
    scanf("%d",&n);
    ans = n;
    L1 = InitList(L1,n);
    scanf("%d",&n);
    L2 = InitList(L2,n);
    printf("输出交集:");
    printList(Intersection01(L1,L2));//输出交集
    //differentSet(L1,L2);//求差集,不开空间存储
    //L1 = DeleteList(L1,5);//测试删除功能;
    LinkList L = differentSet01(L1,L2);//求差集
   printf("输出差集:");
    printList(L);//输出差集

   printf("输出并集:");
   //输出并集
   printList(Unionset(L1,L2));
    return 0;
}

数据结构链表可以用于实现动态数组,支持元素的插入、删除和查找操作。要将链表从小到大排列,你可以采用归并排序或冒泡排序的思想。这里简单描述一种插入排序的方式: 1. 遍历整个链表,对于每个节点,将其值与已排序部分的最后一个节点比较,如果当前值小于后者,就将它插入到适当位置,保持链表有序。 至于链表的集合运算(交集并集差集),由于链表不是哈希集合,通常需要遍历整个链表来进行操作。以下是基本步骤: - **交集**:对于两个链表,遍历它们,只保留同时存在于两个链表中的节点,形成一个新的链表。 - **并集**:遍历第一个链表,然后遍历第二个链表,将所有节点添加到新的链表中,不检查是否已经存在。 - **差集**:首先计算并集,然后再遍历一次第一个链表,移除那些在第二个链表中存在的节点。 以下是简单的伪代码示例: ```python # 假设ListNode是一个链表节点类 def sort_linked_list(head): # 实现排序... def intersect_lists(list1_head, list2_head): # 创建空链表存储结果 result = ListNode(None) current = result while list1_head and list2_head: if list1_head.val <= list2_head.val: current.next = list1_head list1_head = list1_head.next else: current.next = list2_head list2_head = list2_head.next current = current.next return result.next # 对于并集差集,需要先做并集再做差集 def union_and_difference(list1_head, list2_head): union_result = intersect_lists(list1_head, list2_head) difference_result = copy.deepcopy(list1_head) # 或者从头开始遍历list1 current = union_result while current: next_in_list1 = find_node_in_list(difference_result, current.val) if not next_in_list1: difference_result.next = current difference_result = difference_result.next current = current.next return union_result, difference_result ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值