码迷,mamicode.com
首页 > 其他好文 > 详细

判断两条链表是否交叉,若有交叉,返回交叉节点的指针。

时间:2019-04-13 23:36:25      阅读:149      评论:0      收藏:0      [点我收藏+]

标签:type   节点   判断   ons   pch   https   sha   for   template   

上周面试挂了,反思原因,莫非是因为一道算法题没做好吗?这题目是“判断两条链表是否交叉,若有交叉,返回交叉节点的指针。” 为了防止反复在同一个阴沟里翻船,决定把最优解写出来。

#include "pch.h"
#include <iostream>

template<typename T>
class List {
public:
    struct Node {
        T data;
        Node* next;
        Node(T& d, Node* ntx = nullptr) : data(d), next(ntx) {}
    };
    Node* mHead = nullptr;
public:
    //List(){}
    ~List() {
        Node* pcur = mHead, *pnext = nullptr;
        while (pcur) {
            pnext = pcur->next;
            delete pcur;
            pcur = pnext;
        }
    }
    bool AddNode(T dt, bool attail = true) {
        Node*ptr = new Node(dt);
        return AddNode(ptr, attail);
    }
    bool AddNode(Node* nd, bool attail = true) {
        if (nd) {
            if (attail) {
                Node* ptail = Tail();
                if (ptail) {
                    ptail->next = nd;
                }
                else {
                    mHead = nd;
                }
            }
            else {
                nd->next = mHead;
                mHead = nd;
            }
            return true;
        }
        return false;
    }
    Node* Intersect(List& oth) {
        Node* lptr = nullptr, *sptr = nullptr;
        {
            const int sz1 = Size();
            const int sz2 = oth.Size();
            int num = 0;
            if (sz1 >= sz2) {
                lptr = mHead;
                sptr = oth.mHead;
                num = sz1 - sz2;
            }
            else {
                lptr = oth.mHead;
                sptr = mHead;
                num = sz1 - sz2;
            }
            for (int i = 0; i < num; ++i) {
                if (lptr) {
                    lptr = lptr->next;
                }
            }
        }
        while (lptr && sptr) {
            if (lptr == sptr) {
                return lptr;
            }
            lptr = lptr->next;
            sptr = sptr->next;
        }
        return nullptr;
    }

private:
    Node* Tail() {
        Node* ptr = mHead;
        while (ptr && ptr->next) {
            ptr = ptr->next;
        }
        return ptr;
    }
    int Size() {
        int sz = 0;
        Node* ptr = mHead;
        while (ptr) {
            ++sz;
            ptr = ptr->next;
        }
        return sz;
    }
};

int main()
{
    std::cout << "Hello World!\n"; 
    List<int> list1, list2;
    for (int i = 1; i < 3; ++i) {
        list1.AddNode(i);
    }
    for (int i = 25; i < 28; ++i) {
        list2.AddNode(i);
    }

#if 1
    for (int i = 100; i < 101; ++i) {
        List<int>::Node* node = new List<int>::Node(i);
        list1.AddNode(node);
        list2.AddNode(node);
    }
#endif
    auto ptr = list1.Intersect(list2);
    if (ptr) {
        std::cout << "intersect point at " << ptr << std::endl;
    }
    else {
        std::cout << "no intersection\n";
    }

    return 0;
}

代码创建了两条有交叉节点的链表。如图所示:
技术图片

程序运行结束时,析构这两条链表,发生错误,是因为交叉节点被两次释放:
技术图片

判断两条链表是否交叉,若有交叉,返回交叉节点的指针。

标签:type   节点   判断   ons   pch   https   sha   for   template   

原文地址:https://blog.51cto.com/frankniefaquan/2378379

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!