我思故我在系列—数据结构题(题目搜集整理者V_JULY_V,非常感谢!)

来源:互联网 发布:翼龙955软件超频 编辑:程序博客网 时间:2024/05/09 19:51

  

     明天的问题尚未知晓就为之焦虑,昨天的问题已然完结仍无法释怀。生命在于发展,如果害怕新的东西,停滞不前,那么我们就是在拒绝生命。

              ——摘自 奥格.曼狄诺《羊皮卷》


第7 题
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,比如h1,h2,判断这俩个链表是否相交。
为了简化问题,我们假设俩个链表均不带环。
4
问题扩展:
1.如果链表可能有环列?
2.如果需要求出俩个链表相交的第一个节点列?

解题要点:

    1.判断是否带有环;

    2.若是不带环,两种判断相交的方法,利用环找到相交点;

    3.若是带环,判断一链表上俩指针相遇的那个节点,在不在另一条链表上。如果在,则相交,如果不在,则不相交。

#include <iostream>
#include<assert.h>
using namespace std;

class Node{
    public:
    Node(int d):data(d), next(NULL){}
    int data;
    Node* next;
};

void displayLinkList(Node* head, int n)
{
    assert(head!=NULL);/*细节但很重要的入参检查;*/
    n = n+3;/*为什么这里要加上一个数值呢?为了方便从输出结果验证链表是否带环阿!*/
    for (int i = 0; i < n && head; i++, head = head->next)
            {
                cout << head->data << " ";
            }
    cout << endl;
}

/*判断是否是带环链表.并且找出环的入口节点*/
Node* findLoopPort(Node* head)
{
    Node* fast = head;
    Node* slow = head;
    while (fast && fast->next)
        {
                slow = slow->next;
                fast = fast->next->next;
                if(fast==NULL || fast->next==NULL)/*链表不带环*/
                        {
                                    return NULL;
                         }
                if (slow == fast)/*fast与slow两个指针相遇,该链表带有环*/
                break;

        }
  slow = head;/*fast指针从交点出发,slow从头指针出发,再次相遇为环的入口*/
  while (slow != fast)
          {
     slow = slow->next;
     fast = fast->next;
        }
  return slow;/*slow指向环的入口*/
}
void IsExitLoop(Node *head, int n)
{
    displayLinkList(head, n);
    Node *result = findLoopPort(head);
    if (result!=NULL)
     {
          cout << "head has loop,loop port is :"<<result->data << endl;
    }
    else
   {
        cout << "head does not have loop" << endl;
   }
}

/*,两个不带环的单链表,将其中一个单链表形成环,判断另一个是否有环,没有环则不相交;两个单链表若是有相交,则从相交点到尾节点都相同*/
Node* intersect3(Node *head1, Node *head2)
{
    assert(head1!=NULL && head2!=NULL);
 Node* tail2 = head2;
 while (tail2->next)
    tail2 = tail2->next;
 tail2->next = head2;

Node* result = findLoopPort(head1);
tail2->next = NULL;
return result;
}
void testIntersect3(Node *head1, Node *head2)
{
        if (intersect3(head1, head2)!=NULL)
                cout << "intersect" << endl;
        else
                cout << "not intersect" << endl;
}

/*两个不带环的单链表,若他们的尾指针相同,则相交,时间复杂的o(head1.length+head2.length),o(n)级别,空间复杂的o(1)*/
bool intersect4(Node *head1, Node *head2)
{
    assert(head1!=NULL && head2!=NULL);
    Node *tail1 = head1;
    Node *tail2 = head2;
    while (tail1->next)
            tail1 = tail1->next;
    while (tail2->next)
            tail2 = tail2->next;

    return tail1 == tail2;
}
void testIntersect4(Node *head1, Node *head2)
{
        if (intersect4(head1, head2))
                cout << "intersect" << endl;
        else
                cout << "not intersect" << endl;
}

/*找到两个链表相交点*/
Node *findFirstIntersection(Node *head1, Node *head2)
{
        assert(head1!=NULL && head2!=NULL);
        int len1 = 1;
        int len2 = 1;
        bool result = false;
        Node *p = head1;
        Node *q = head2;
        while (p->next)
        {
                len1 ++;
                p = p->next;
        }
        while (q->next)
        {
            len2 ++;
            q = q->next;
        }
        result = (p == q);
        if (result)/*倘若两个链表的长度不相等*/
        {
            int steps = abs(len1 - len2);
            Node *head = (len1 > len2) ? head1 : head2;
            while (steps!=0)
                 {
                   head = head->next;
                   steps --;
                 }
            /*head指向长的链表,并且先行steps步长*/
    (len1 > len2) ? (p = head, q = head2) : (p = head1, q = head);
    while (p != q)/*此后,两个指针再相遇点为第一个交点*/
               {
        p = p->next;
        q = q->next;
                 }
   return p;
          }
return NULL;
}
void testFindFirstIntersection(Node* head1, Node* head2)
{
    Node* result = findFirstIntersection(head1, head2);
    if (result == NULL)
    {
        cout << "no intersection" << endl;
    }
else
   {
     cout << "first intersection is " << result->data << endl;
   }

}

int main()
{
    int i;
  Node *head1 = NULL;
  Node *head2 = NULL;

 /*create a cyclelink:head1*/
  Node *tail = NULL;
for (i = 0; i < 10; i ++)
{
   Node *p = new Node(i + 1);
   if (head1 == NULL)
        {
     head1 = p;
     tail = head1;
        }
   else
       {
     tail->next = p;
     tail = p;
        }
}
Node *p = head1;
for (i = 1; i < 5; i ++)
   p = p->next;
tail->next = p;

/*create a link withou cycle*/
tail = NULL;
for (i = 0; i < 10; i ++)
{
   Node *p = new Node(i + 1);
   if (head2 == NULL)
       {
    head2 = p;
       }
   else
        {
    tail->next = p;
        }
    tail = p;
}

IsExitLoop(head1, 10);
IsExitLoop(head2, 10);

/*another mothod to create links*/
Node *head3 = NULL;
Node *head4 = NULL;
Node *p1 = new Node(1);
Node *p2 = new Node(2);
Node *p3 = new Node(3);
Node *p4 = new Node(4);
Node *p5 = new Node(5);
Node *p11 = new Node(11);
Node *p12 = new Node(12);
Node *p13 = new Node(13);
Node *p14 = new Node(14);
Node *p15 = new Node(15);
head3 = p1;
p1->next = p2;
p2->next = p3;
p3->next = p4;
p4->next = p5;
head4 = p11;
p11->next = p12;
p12->next = p13;
p13->next = p14;

/*此时,两个链表相交*/

p14->next=p3;
p15->next = p13;
testIntersect3(head3, head4);
testIntersect4(head3, head4);
testFindFirstIntersection(head3, head4);

/*此时,两个链表不相交*/

p14->next=p15;
p15->next = NULL;
testIntersect3(head3, head4);
testIntersect4(head3, head4);
testFindFirstIntersection(head3, head4);

delete p;
delete p1;
delete p2;
delete p3;
delete p4;
delete p5;
delete p11;
delete p12;
delete p13;
delete p14;
delete p15;

return 1;
}

                                                       

原创粉丝点击