37. 两个链表的第一个公共结点

  题目:输入两个链表,找出它们的第一个公共结点。

  思路:先遍历两个链表得出它们各自的长度,然后让长链表先走,直到长度和短的一致,然后两个链表一起走。

  相关题目:
  如果把图5.3(两个链表重复结点的Y型图)逆时针旋转90度,我们就会发现两个链表的拓扑形状和一棵树的形状非常相似,只是这里的指针式从叶结点指向根结点的。两个链表的第一个公共结点正好是二叉树中两个叶节点的最低公共祖先。

#include<iostream>
#include<cstdio>
using namespace std;

struct ListNode
{
    int         m_nValue;
    ListNode*   m_pNext;
};

//创建链表节点
ListNode* CreateListNode(int value)
{
    ListNode* pNode = new ListNode();
    pNode->m_nValue = value;
    pNode->m_pNext = NULL;

    return pNode;
}

//链接链表节点
void ConnectListNodes(ListNode* pCurrent, ListNode* pNext)
{
    if (pCurrent == NULL)
    {
        cout << "Error to connect two nodes." << endl;
        return;
    }

    pCurrent->m_pNext = pNext;
}

//打印链表
void PrintListNode(ListNode* pHead)
{

    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        cout << pNode->m_nValue << "  ";
        pNode = pNode->m_pNext;
    }

    cout << endl << "PrintList end." << endl;
}

//销毁链表节点
void DestroyList(ListNode* pHead)
{
    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        pHead = pHead->m_pNext;
        delete pNode;
        pNode = pHead;
    }
}


unsigned int GetListLength(ListNode* pHead)
{
    unsigned int length = 0;
    ListNode* pNode = pHead;
    while (pNode != NULL)
    {
        ++length;
        pNode = pNode->m_pNext;
    }

    return length;
}

ListNode* FindFirstCommomNode(ListNode* pHead1, ListNode* pHead2)
{
    //得到两个链表的长度
    unsigned int length1 = GetListLength(pHead1);
    unsigned int length2 = GetListLength(pHead2);
    int lengthdiff = length1 - length2;             //判断哪个长哪个短

    ListNode* longList = pHead1;
    ListNode* shortList = pHead2;
    if (length2 > length1)
    {
        longList = pHead2;
        shortList = pHead1;
        lengthdiff = length2 - length1;
    }

    //先在长链表上走几步,再同时在两个链表上遍历
    for (int i = 0; i < lengthdiff; i++)
    {
        longList = longList->m_pNext;
    }

    while ((longList != NULL) && (shortList != NULL) && (longList != shortList))
    {
        longList = longList->m_pNext;
        shortList = shortList->m_pNext;
    }

    //得到第一个公共结点
    ListNode* firstCommonNode = longList;

    return firstCommonNode;
}

void test1()
{
    ListNode* node1 = CreateListNode(1);
    ListNode* node2 = CreateListNode(2);
    ListNode* node3 = CreateListNode(3);
    ListNode* node4 = CreateListNode(4);
    ListNode* node5 = CreateListNode(5);
    ListNode* node6 = CreateListNode(6);
    ListNode* node7 = CreateListNode(7);

    ConnectListNodes(node1, node2);
    ConnectListNodes(node2, node3);
    ConnectListNodes(node3, node6);
    ConnectListNodes(node6, node7);

    PrintListNode(node1);

    ConnectListNodes(node4, node5);
    ConnectListNodes(node5, node6);
    ConnectListNodes(node6, node7);

    PrintListNode(node4);

    ListNode* node = FindFirstCommomNode(node1, node4);
    cout << node->m_nValue << endl;

    //DestroyList(node1);
    //DestroyList(node4);  //这边销毁得用DestroyNode,一个一个的销毁
}

int main()
{
    test1();

    return 0;
}

猜你喜欢

转载自my.oschina.net/134596/blog/1800856