【问题标题】:Distance between two nodes in circular linked list循环链表中两个节点之间的距离
【发布时间】:2018-04-01 08:51:36
【问题描述】:

我想在一个循环链表中找到两个节点之间的距离(它们之间的节点数)。

节点在哪里:

typedef struct node
{
    int data;
    struct node *next;
}nodal;

nodal *distance(nodal *start)
{
    int n1,n2,d1=0,d2=0,c=0;
    if(start==NULL)
    {
        printf("\nList is empty");
    }
    else
    {
        printf("\nEnter the fist node element : ");
        scanf("%d",&n1);
        printf("\nEnter the second node element : ");
        scanf("%d",&n2);
        nodal *ptr=start;
        while(ptr->next!=start)
        {
            c++;
            if(ptr->data==n1)
            {
                d1=c;
            }
            if(ptr->data==n2)
            {
                d2=c;
            }
        }
    }
    printf("The distance between two nodes is %d",(d2-d1));
    return start;
}

我没有给出任何输出。

还假设循环列表是否包含以下数据:

1,2,3,4,5,6,7,8,9

如果我提供意见

第一个节点元素为 9

第二个节点元素为 4

那么这个算法就行不通了。 有什么改变的建议吗?

【问题讨论】:

  • typo ,你在两个if 语句中都与 n1 进行比较
  • 仍然没有输出@JoshGreifer
  • 在第二种情况下,您有一个错字:必须是 n2
  • 无输出是什么意思?程序挂起?
  • 是的 @0andriy 它挂了

标签: c data-structures linked-list circular-list


【解决方案1】:

找到第一个节点时开始计数,找到第二个节点时停止计数,例如:

int inc = 0, dist = 0;

if (n1 == n2) {
    return 0;
}
node = start;
while (node) {
    dist += inc;
    if ((node->data == n1) || (node->data == n2)) {
        if (inc++ == 1) return dist;
    }
    node = node->next;
    if (node == start) break;
}
return 0;

【讨论】:

  • 你能解释一下 while(node) 的用法吗? @KeineLust
  • while (node) = while (node != NULL),在指针指向与NULL不同的有效区域时执行一些任务
  • 很好的解决方案,适用于循环和 NULL 终止列表。
  • 这里有一个更简单的版本:int inc = 0, dist = 0; node = start; while (node) { dist += inc; if ((node->data == n1) || (node->data == n2)) { if (inc++ == 1) return dist; } node = node->next; if (node == start) break; } return 0; } 第一个测试是有问题的:如果列表有重复节点怎么办?
  • 请注意,扫描可能会在n1 之前找到n2 并返回不同的距离,不一定更小。可能不是预期的。
【解决方案2】:

首先你必须去第一个输入的元素,在这个过程中计数不会增加。然后开始增加计数,直到到达第二个元素。

代码如下:

ptr=start;
while(ptr->data!=n1)
{
   ptr=ptr->next;
}
//---now we have reached the first number----

while(ptr->data!=n2)
{
  count++;
ptr=ptr->next;
}

【讨论】:

  • 如果循环列表不包含两个节点,则无限循环,
  • 我只是按照要求的测试用例回答了,
【解决方案3】:

您的代码中存在多个问题:

  • 对列表末尾的测试会阻止您测试最后一个节点。
  • 您通过返回0 来处理n1 == n2 的情况,这可能不是预期的。
  • 如果n2出现在n1之前,n1n2之间的距离将为负数,这是不正确的:由于列表是循环的,如果你在n1之后继续扫描,你会遇到@987654328 @ 在包裹第一个节点后最多为正距离。

这是一个替代解决方案:

typedef struct node {
    int data;
    struct node *next;
} nodal;

nodal *distance(nodal *start) {
    int n1, n2, d1 = 0, d2 = 0, length = 0;
    if (start == NULL) {
        printf("List is empty\n");
    } else {
        printf("\nEnter the fist node element : ");
        if (scanf("%d", &n1) != 1) {
            printf("invalid input\n");
            return start;
        }
        printf("\nEnter the second node element : ");
        if (scanf("%d", &n2) != 1) {
            printf("invalid input\n");
            return start;
        }
        nodal *ptr = start;
        for (;;) {
            length++;
            if (ptr->data == n1 && !d1) {
                d1 = length;
            } else if (ptr->data == n2) {
                if (d1) {
                    d2 = length;
                    break;
                }
                if (!d2)
                    d2 = length;
            }
            ptr = ptr->next;
            if (ptr == start)
                break;
        }
    }
    if (d1 && d2) {
        int dist = d2 - d1;
        if (dist < 0)
            dist += length;
        printf("The distance between node(%d) and node(%d) is %d\n", d1, d2, dist);
    } else {
        if (d2)
            printf("node(%d) not found\n", d1);
        if (d1)
            printf("node(%d) not found\n", d2);
    }
    return start;
}

【讨论】:

    猜你喜欢
    • 2019-03-29
    • 1970-01-01
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-28
    相关资源
    最近更新 更多