📜  两个链表的并集和相交(1)

📅  最后修改于: 2023-12-03 15:35:56.933000             🧑  作者: Mango

两个链表的并集和相交
介绍

链表是一种常见的数据结构,其中的元素被链接在一起形成一个链式结构。在实际开发中,我们通常需要对两个链表进行操作,包括求它们的并集和相交。

并集指的是两个链表中所有的节点的集合,相交指的是两个链表中共有的节点的集合。

在程序中,我们通常使用指针来遍历链表,从而对其进行操作。

实现

链表定义

在实现之前,我们需要先定义链表节点的数据结构。

struct ListNode {
    int val;
    struct ListNode *next;
};

其中,val表示节点的值,next指向下一个节点。

求并集

对于两个链表,我们可以先将它们的节点值放入一个集合中,然后遍历该集合,依次创建新的链表节点。

struct ListNode* getUnion(struct ListNode* l1, struct ListNode* l2) {
    if (!l1 && !l2) {
        return NULL;
    }

    // 创建用于存放节点值的集合
    set<int> s;

    // 遍历l1链表,将节点值添加到集合中
    while (l1) {
        s.insert(l1->val);
        l1 = l1->next;
    }

    // 遍历l2链表,将不在集合中的节点值添加到集合中
    while (l2) {
        if (!s.count(l2->val)) {
            s.insert(l2->val);
        }
        l2 = l2->next;
    }

    // 遍历集合,创建新的链表节点并连接起来
    struct ListNode* head = NULL;
    struct ListNode* tail = NULL;

    for (auto val : s) {
        struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
        node->val = val;
        node->next = NULL;

        if (!head) {
            head = node;
            tail = node;
        } else {
            tail->next = node;
            tail = node;
        }
    }

    return head;
}

在这个实现中,我们使用了set集合来存放节点值,这样可以避免重复元素的问题。

求相交

对于两个链表,我们可以先分别计算它们的长度,然后将较长的链表先移动一定步数,使其和较短的链表起点位置相同,然后同时遍历两个链表,找到第一个相同的节点。

struct ListNode* getIntersection(struct ListNode* l1, struct ListNode* l2) {
    if (!l1 || !l2) {
        return NULL;
    }

    // 计算l1和l2的长度
    int len1 = 0, len2 = 0;
    struct ListNode* p1 = l1;
    struct ListNode* p2 = l2;

    while (p1) {
        len1++;
        p1 = p1->next;
    }

    while (p2) {
        len2++;
        p2 = p2->next;
    }

    // 让较长的链表先移动一定步数
    p1 = l1;
    p2 = l2;

    int diff = abs(len1 - len2);

    if (len1 < len2) {
        swap(p1, p2);
    }

    for (int i = 0; i < diff; i++) {
        p1 = p1->next;
    }

    // 同时遍历两个链表,找到第一个相同的节点
    while (p1 && p2) {
        if (p1 == p2) {
            return p1;
        } else {
            p1 = p1->next;
            p2 = p2->next;
        }
    }

    return NULL;
}
总结

以上就是求两个链表并集和相交的实现。在实际开发中,我们要根据具体的需求选择合适的算法和数据结构来实现。

至此,两个链表的并集和相交介绍完毕.