zoukankan      html  css  js  c++  java
  • 判断两个链表是否相交

     微软亚院之编程----判断两个链表是否相交

    给出两个单向链表的头指针,比如h1,h2,判断这两个链表是否相交。

     

    分析:

    (1)先判断链表有无环,如果一个有环,一个没有环,则说明两个链表肯定不会相交。

    (2)如果两个链表都没有环,则如果两个链表相交,两个链表的最后一个结点肯定是同一个结点。

    (3)如果两个链表h1,h2都有环,则可以找到两个链表上并且在环上的任何一个结点p1和p2。如果从结点p1开始遍历链表h1,能够遍历到p2,说明两个链表相交;否则从p1开始遍历h1,遍历一圈后又回到p1,而未遍历到p2,说明两个链表不相交。

    (4)检查单链表是否有环的方法:

      使用两个指针p1,p2 从链表头开始遍历,p1 每次前进一步,p2 每次前进两步。如果p2 到达链表尾部,说明无环,否则p1、p2 必然会在某个时刻相遇(p1==p2),从而检测到链表中有环。

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef int ElemType;
    
    //定义链表的存储结构
    typedef struct Node {
        ElemType data;
        struct Node *next;
    } Node;
    typedef struct Node *LinkList;
    typedef struct Node *pNode;
    
    //判断两个链表是否相交
    int isListJoined(pNode p1, pNode p2);
    
    //判断单链表有无环,如果有环,返回环上的任意结点,否则返回NULL
    pNode testCycle(LinkList L);
    
    //假设两个单链表都没有环
    int isJoinedSimple(pNode h1, pNode h2);
    
    //创建单链表(n表示链表长度,isCycle表示是否有环)
    LinkList createLinkList(int n, int isCycle);
    
    
    //判断两个链表是否相交
    int isListJoined(pNode p1, pNode p2) {
        
        pNode cycle1 = testCycle(p1);
        pNode cycle2 = testCycle(p2);
        
        if ((cycle1 != NULL && cycle2 == NULL) || (cycle1 == NULL && cycle2 != NULL)) {
            //如果一个有环,一个没有环
            return 0;
        }
        if (cycle1 == NULL && cycle2 == NULL) {
            //两个都没有环
            return isJoinedSimple(p1, p2);
        }
        
        //两个都有环
        pNode p = cycle1;
        while (1) {
            if (p == cycle2 || p->next == cycle2) {
                return 1;
            }
            p = p->next->next;
            cycle1 = cycle1->next;
            if (p == cycle1) {
                return 0;
            }
        }
    }
    
    //判断单链表有无环,如果有环,返回环上的任意结点,否则返回NULL
    pNode testCycle(LinkList L) {
        pNode p1 = L;
        pNode p2 = L;
        while (p2 != NULL && p2->next != NULL) {
            p1 = p1->next;
            p2 = p2->next->next;
            if (p1 == p2) {
                return p1;
            }
        }
        return NULL;
    }
    
    //假设两个单链表都没有环
    int isJoinedSimple(pNode h1, pNode h2) {
        while (h1->next) {
            h1 = h1->next;
        }
        while (h2->next) {
            h2 = h2->next;
        }
        if (h1 == h2) {
            return 1;
        }
        return 0;
    }
    
    //创建单链表
    LinkList createLinkList(int n, int isCycle) {
        LinkList L = NULL;
        pNode p, r = NULL;
        ElemType e;
        for (int i = 0; i < n; i++) {
            printf("请输入第%d个数字", i + 1);
            scanf("%d", &e);
            p = (pNode)malloc(sizeof(Node));
            if (p == NULL) {
                printf("out of space");
                exit(1);
            }
            p->data = e;
            if (i == n-1 && isCycle == 1) {
                p->next = L;          //此处是让链表的尾结点的next指针指向头结点
            } else {
                p->next = NULL;
            }
            if (L == NULL) {
                L = p;
            } else {
                r->next = p;
            }
            r = p;
        }
        return L;
    }
    
    
    int main(int argc, const char * argv[]) {
        
        //创建两个没有环的链表,并且不相交
        LinkList h1 = createLinkList(10, 0);
        LinkList h2 = createLinkList(5, 0);
        
        int isJoined1 = isListJoined(h1, h2);
        printf("%d", isJoined1);
        
        
        //创建两个没有环的链表,并且相交
        LinkList h3 = createLinkList(5, 0);
        LinkList h4 = h3;
        
        int isJoined2 = isListJoined(h3, h4);
        printf("%d", isJoined2);
        
        
        //创建两个有环的链表,并且不相交
        LinkList h5 = createLinkList(5, 1);
        LinkList h6 = createLinkList(4, 1);
        
        int isJoined3 = isListJoined(h5, h6);
        printf("%d", isJoined3);
        
        
        //创建两个有环的链表,并且相交
        LinkList h7 = createLinkList(5, 1);
        LinkList h8 = h7;
        
        int isJoined4 = isListJoined(h7, h8);
        printf("%d", isJoined4);
        
        return 0;
    }
  • 相关阅读:
    WCF、Net remoting、Web service概念及区别
    新浪微博技术架构分析
    谈SOA和云的分层架构
    开发人员眼中最好的代码编辑器是什么?
    调试脚本,远离alert
    struts2与cookie实现自动登录和验证码验证
    把旧的项目改变名称重新部署到tomcat下发现项目名称还是原来的项目名称,解决方案
    myeclipse2014 安装maven3.3.9和mave配置本地仓库
    mysql在表的某一位置增加一列、删除一列、修改列名
    Java实现对cookie的增删改查
  • 原文地址:https://www.cnblogs.com/muzijie/p/5664518.html
Copyright © 2011-2022 走看看