画圆的沙滩

亦简亦美

相交的链表

下面的代码尝试解决带环和不带环的链表是否相交以及如果相交,交点的位置两个问题。见编程之美3.6节,代码应当同时解决了后面的两个扩展问题。

Node* commonEnd(Node* a, Node* b) {
if (!a || !b) return 0;

Node
*p1 = a, *p2 = a;
do {
if (p2->next) p2 = p2->next;
if (p2->next) p2 = p2->next;
if (p1->next) p1 = p1->next;
}
while (p1 != p2);

Node
*q1 = b, *q2 = b;
do {
if (q2 == p1) return p1;
if (q2->next) q2 = q2->next;
if (q2 == p1) return p1;
if (q2->next) q2 = q2->next;
if (q1->next) q1 = q1->next;
}
while (q1 != q2);

return 0;
}

int distance(Node* a, Node* b) {
if (a && b) {
if (a == b) return 0;

Node
* p1 = a, *p2 = a;
int d = 0;
do {
if (p2->next) p2 = p2->next, ++d;
if (p2 == b) return d;
if (p2->next) p2 = p2->next, ++d;
if (p2 == b) return d;
if (p1->next) p1 = p1->next;
}
while (p1 != p2);
}

return -1;
}

Node
* step(Node* a, int n) {
while (n-- && a) a = a->next;
return a;
}

Node
* intersection(Node* a, Node* b) {
Node
* end = commonEnd(a, b);
if (!end) return 0;
int da = distance(a, end), db = distance(b, end);

if (da > db) a = step(a, da - db);
else b = step(b, db - da);

while (a != b) a = a->next, b = b->next;
return a;
}

posted on 2011-03-21 13:44  acmaru  阅读(176)  评论(0编辑  收藏  举报

导航