判断两条单链表是否相交

        算法中经常会判断两条单链表是否相交,虽然算法简单,但也值得说一下。代码中有详尽注释, Show you the code !

#undef UNICODE

#include <iostream>
#include <Windows.h>
#include <cstring>

using namespace std;

typedef struct _SINGLE_LIST {
    _SINGLE_LIST *Next;
    char Tag;
} SINGLE_LIST, *PSINGLE_LIST;

void main()
{
    PSINGLE_LIST Entry = NULL;
    char TagIndex = 'A';
    PSINGLE_LIST Head1 = (PSINGLE_LIST)malloc(sizeof(SINGLE_LIST));
    Entry = Head1;
    Entry->Tag = TagIndex++;
    Entry->Next = NULL;

    for (int i = 0; i < 6; i++) {
        Entry->Next = (PSINGLE_LIST)malloc(sizeof(SINGLE_LIST));
        Entry->Next->Tag = TagIndex++;
        Entry->Next->Next = NULL;
        Entry = Entry->Next;
    }

    PSINGLE_LIST Head2 = (PSINGLE_LIST)malloc(sizeof(SINGLE_LIST));
    Entry = Head2;
    Entry->Tag = TagIndex++;
    Entry->Next = NULL;
    for (int i = 0; i < 3; i++) {
        Entry->Next = (PSINGLE_LIST)malloc(sizeof(SINGLE_LIST));
        Entry->Next->Tag = TagIndex++;
        Entry->Next->Next = NULL;
        Entry = Entry->Next;
    }

    // 构造一个交点
    Entry->Next = Head1->Next->Next->Next;

    // 下图即为此时两个链表的连接情况
    // +--------------------------------------------+
    // |   A -> B -> C -> D -> E -> F -> G          |
    // |                  ^                         |
    // |                  |                         |
    // |   H -> I -> J -> K                         |
    // +--------------------------------------------+

    // 方法一: 
    // 循环遍历第一个链表中的每一项,查看是否在第二个链表中,因为两个单链表相交
    // 遍历其中任一链表,至少一个或多个项在第二个链表中。在最坏的情况下,将运算
    // m*n 次。 算法如下:
    BOOL IsIntersect = FALSE;
    PSINGLE_LIST IntersectEntry = NULL;
    Entry = Head1;
    while (Entry != NULL) {
        PSINGLE_LIST Entry2 = Head2;
        while (Entry2) {
            if (Entry == Entry2) {
                IsIntersect = TRUE;
                IntersectEntry = Entry;
                goto Result;
            }
            Entry2 = Entry2->Next;
        }

        Entry = Entry->Next;
    }

Result:
    if (IsIntersect) {
        //cout << "Intersect: " << "True.   " << "Tag - " << IntersectEntry->Tag  << endl;
        cout << "Intersect: " << "True." << endl;
    } else {
        cout << "Intersect: " << "False" << endl;
    }

    // 方法二: 
    // 观察上图不难发现如果两个单链表相交,那么最后一个项必然相同。所以如果站在只判断单
    // 链表是否相交的角度来看,算法其实可以更简单。两个链表各遍历一遍,找到最后一个项,
    // 检查是否相同。运算次数为 m+n。 算法如下:
    PSINGLE_LIST LastEntry1 = NULL;
    PSINGLE_LIST LastEntry2 = NULL;
    Entry = Head1;
    while (Entry != NULL) {
        Entry = Entry->Next;
    }
    LastEntry1 = Entry;

    Entry = Head2;
    while (Entry != NULL) {
        Entry = Entry->Next;
    }
    LastEntry2 = Entry;

    if (LastEntry1 == LastEntry2) {
        IsIntersect = TRUE;
    }

    if (IsIntersect) {
        //cout << "Intersect: " << "True.   " << "Tag - " << IntersectEntry->Tag  << endl;
        cout << "Intersect: " << "True." << endl;
    } else {
        cout << "Intersect: " << "False" << endl;
    }
}

        这就是编程之美,相同的问题采用不同的方法,效果完全不同。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值