C++ 在元素数为偶数的情况下打印链接列表的中间部分

C++ 在元素数为偶数的情况下打印链接列表的中间部分,c++,algorithm,C++,Algorithm,我知道如何通过两个指针以不同的速度移动来打印给定链表的中间部分。第一个指针移动一个位置,而第二个指针移动两个位置。现在,如果链表包含偶数个节点,也就是说,4个节点,那么,从技术上讲,哪一个是中间节点。另外,我在while循环中用于打印的条件是 fastptr = head; slowptr = head; while (fastptr->next->next != NULL && slowptr->next != NULL) { slowptr = s

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

fastptr = head;
slowptr = head;

while (fastptr->next->next != NULL && slowptr->next != NULL)
{
    slowptr = slowptr->next;
    fastptr = fastptr->next->next;
}
在这种情况下,如果我手动运行上述代码一次,那么当
slowptr
位于第二个节点且
fastptr
位于第三个节点时,代码将停止。这是正确的吗

现在,如果链表包含偶数个节点,也就是说,4个节点,那么,从技术上讲,哪一个是中间节点

可以是:

  • 第二个
  • 第三个
  • 两者都没有,即使是长度列表也没有中间值
。。。取决于你对“中间”的具体定义。参考你的作业以获得正确的解释,如果没有明确说明,则使用最方便的含义

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


对。(假设“3个节点”是指“第三个节点”,而不是“第四个节点”,如果使用基于零的索引系统,则会是第四个节点)

您可以选择第二个或第三个节点作为中间节点(如果节点数为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.

< >编辑:检查列表是否为空。

< P>,它将更加清晰可见,请考虑下面的演示程序

#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;
    }       
} 
因此,当数组中有偶数或奇数元素时,您可以看到输出的元素

如何重写列表的代码

它可以如下所示

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)
fastptr
fastptr->next
都可以等于NULL。因此,代码具有未定义的行为。

1)对于现在访问此问题的人, 如果考虑元素的NO= 4</P>
    如果你把2看成中间元素 那么情况应该是

     while(fast_ptr->next->next != head) 
    
     while(fast_ptr != head)
    
    < L>>P>如果将3作为中间元素,则条件应为

     while(fast_ptr->next->next != head) 
    
     while(fast_ptr != head)
    
2) 对于奇数元素,条件为:

 while(fast_ptr->next != head)
所以1)和2一起


一般为第二例,3为中间元素。

如果<代码> FASPTR>> Next=NULL/<代码>,您的代码将崩溃。尝试不同的情况,看看会发生什么。请问您的代码将在哪个中间?或者你的代码应该在哪个中间呢?第一个很容易确定。第二个是您的选择。您给出的示例主要以n/2元素作为中间元素(基于1的索引)。这总是真的吗?因此,如果节点数为4,则第二个节点是中间节点(基于1的索引)?@John Lui它对应于表达式(N+1)/2,即当N为奇数时,例如等于3,则将输出第二个元素。噢!正确的。知道了。所以标准表达式是
(n+1)/2
,对吗?@John Lui查看程序输出。它展示了清晰的方法:哪一个元素将是中间元素。我专门写了这个程序。@John Lui如果要从1开始计算元素,那么是的。
// 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);