在偶数个元素的情况下打印链表的中间

时间:2015-06-12 14:53:02

标签: c++ algorithm

我知道如何通过取两个以不同速度移动的指针来打印给定链表的中间部分。第一个指针移动一个而第二个指针移动两个位置。现在,如果链表包含偶数个节点,也就是说,让我们说4个节点,那么,哪个节点在技术上是中间节点。另外,我在while循环中用于打印的条件是,

fastptr = head;
slowptr = head;

while (fastptr->next->next != NULL && slowptr->next != NULL)
{
    slowptr = slowptr->next;
    fastptr = fastptr->next->next;
}

在这种情况下,如果我手动运行上述代码一次,那么当slowptr位于第二个节点且fastptr位于3个节点时,代码将停止。它是否正确?

4 个答案:

答案 0 :(得分:1)

  

现在,如果链表包含偶数个节点,也就是说,让我们说4个节点,那么哪个节点在技术上是中间的?

可能是:

  • 第二个
  • 第三个
  • 两者都没有,甚至长度列表都没有中间

...取决于您对“中间”的具体定义。请参阅您的作业以获得正确的解释,或者如果没有指定,请使用最方便的任何含义。

  

在这种情况下,如果我手动运行上面的代码一次,那么当slowptr在第二个节点并且fastptr在3个节点时代码将停止。这是对的吗?

是。 (假设“3节点”是指“第三个节点”而不是“第四个节点”,这就是你使用基于零的索引系统时的情况)

答案 1 :(得分:1)

您可以选择第二个或第三个节点为中间(如果节点数为4)。但是大多数时候您会看到第二个节点被视为中间节点。您可以看到以下代码作为您的代码可能会崩溃,例如如果有3个节点。循环一次迭代后,fastptr将指向最后一个节点,fastptr->next->next将崩溃。

 fastptr=head;
 slowptr=head;
 while(fastptr->next!=NULL)//ie continue until fastptr is at lastnode
 {
    fastptr=fastptr->next;
    if(fastptr->next==NULL)//ie last node
    break;
    fastptr=fastrptr->next;
    slowptr=slowptr->next;
  }
  //slowptr is pointing to middle node.

编辑:事先检查列表是否为空。

答案 2 :(得分:1)

考虑以下示范性计划

会更清晰明确
#include <iostream>

int main()
{
    const size_t N = 10;
    int a[N] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    while ( true )
    {
        std::cout << "\nEnter the size of the sub array less than or equal to "
                  << N << " (0 - exit): ";

        size_t n = 0;
        std::cin >> n;

        if ( !n ) break;

        if ( N < n ) n = N;

        size_t i = 0;
        for ( size_t j = 0; j < n && ++j < n && ++j < n; ) i++;

        for ( size_t j = 0; j < n; j++ ) std::cout << a[j] << ' ';
        std::cout << std::endl;
        std::cout << a[i] << std::endl;
    }       
} 

它的输出是

Enter the size of the sub array less than or equal to 10 (0 - exit): 10
0 1 2 3 4 5 6 7 8 9 
4

Enter the size of the sub array less than or equal to 10 (0 - exit): 9
0 1 2 3 4 5 6 7 8 
4

Enter the size of the sub array less than or equal to 10 (0 - exit): 8
0 1 2 3 4 5 6 7 
3

Enter the size of the sub array less than or equal to 10 (0 - exit): 7
0 1 2 3 4 5 6 
3

Enter the size of the sub array less than or equal to 10 (0 - exit): 6
0 1 2 3 4 5 
2

Enter the size of the sub array less than or equal to 10 (0 - exit): 5
0 1 2 3 4 
2

Enter the size of the sub array less than or equal to 10 (0 - exit): 4
0 1 2 3 
1

Enter the size of the sub array less than or equal to 10 (0 - exit): 3
0 1 2 
1

Enter the size of the sub array less than or equal to 10 (0 - exit): 2
0 1 
0

Enter the size of the sub array less than or equal to 10 (0 - exit): 1
0 
0

Enter the size of the sub array less than or equal to 10 (0 - exit): 0

所以当你在数组中有偶数或奇数元素时,你可以看到自己会输出什么元素。

如何重写列表的代码?

它可以看作以下方式

node *slowptr = head;

for ( node * fastptr = head; 
      fastptr  && ( fastptr = fastptr->next ) && ( fastptr = fastptr->next ); )
{
    slowptr = slowptr->next;
}

如果您在head不等于NULL

的循环之前检查,则可以更简单地编写此循环

例如

node *slowptr = head;

if ( slowptr )
{
    for ( node * fastptr = head; 
          ( fastptr = fastptr->next ) && ( fastptr = fastptr->next ); )
    {
        slowptr = slowptr->next;
    }
}

至于你展示的循环那么它是错误的

while (fastptr->next->next != NULL && slowptr->next != NULL)

fastptrfastptr->next每个都可以等于NULL。所以代码有不确定的行为。

答案 3 :(得分:0)

1)对于那些现在正在访问这个问题的人, 如果你认为没有元素= 4

  • 如果你认为2是中间元素 那么条件应该是

     while(fast_ptr->next->next != head) 
    
  • 如果你认为3是中间元素,那么条件应该是

     while(fast_ptr != head)
    

2)对于奇数元素,条件是:

 while(fast_ptr->next != head)

所以一起1)和2

// for 2 as middle element
while(fast_ptr->next != NULL && fast_ptr->next->next != NULL)
{
   fast_ptr = fast_ptr->next->next;
   slow_ptr = slow_ptr->next;
 }
 printf("The middle element is [%d]\n\n", slow_ptr->data); `

// for 3 as middle element
while (fast_ptr != NULL && fast_ptr->next != NULL)
    {
        fast_ptr = fast_ptr->next->next;
        slow_ptr = slow_ptr->next;
    }
    printf("The middle element is [%d]\n\n", slow_ptr->data);

通常是第二种情况,使用3作为中间元素。