在C

时间:2016-06-08 13:16:52

标签: c pointers linked-list palindrome singly-linked-list

我试图检查单链表是否是回文。约束是 - 算法必须是线性时间和恒定空间。

我使用的基本算法如下 -

  1. 快速使用&缓慢的指针将列表分成两半。
  2. 将后半部位移位。
  3. 比较第一和第二半。
  4. 构建原始列表
  5. 返回结果。
  6. 我的实现适用于列表具有偶数个元素但如果元素数量为奇数则失败。

    /*
     * @brief   Checks if a list is a palindrome or not
     */
    bool is_palindrome(node *head)
    {
        node *first;                /* Points to head node of 1st half */
        node *second;               /* Points to head node of 2nd half */
        node *f_ptr = head;         /* Fast pointer */
        node *s_ptr = head;         /* Slow pointer */
        node *prev = NULL;          /* Previous to slow pointer */
        bool ret = false;           /* Return value */
    
        while (f_ptr && f_ptr->next && f_ptr->next->next)
        {
            prev = s_ptr;
            s_ptr = s_ptr->next;
            f_ptr = f_ptr->next->next;
        }
    
        /* List with even number of elements */
        if (!(f_ptr->next->next))
        {
            first = head;
            second = s_ptr->next;
            s_ptr->next = NULL;
            /* Reverse the second half */
            second = reverse_list(&second);
            /* Compare the first & second half */
            ret = are_identical(first, second);
            /* Finally, construct the original list back */
            second = reverse_list(&second);
            s_ptr->next = second;
            print_list(head);
        }
        /* List with odd number of elements */
        if (!(f_ptr->next))
        {
            first = head;
            second = s_ptr->next;
            prev->next = NULL;
            s_ptr->next = NULL;
            /* Reverse the second half */
            second = reverse_list(&second);
            /* Compare the first & second half */
            ret = are_identical(first, second);
            /* Finally, construct the original list back */
            second = reverse_list(&second);
            prev->next = s_ptr; s_ptr->next = second;
            print_list(head);
        }
        return ret;
    }
    

    在处理奇数案件时,有人可以帮我弄清楚我做错了什么吗?可以在here找到该程序的完整实现。

1 个答案:

答案 0 :(得分:1)

感谢s7amuser指出错误。以下是适用于偶数和&奇怪的情况。

/*
 * @brief   Checks if a list is a palindrome or not
 */
bool is_palindrome(node *head)
{
    node *first;                /* Points to head node of 1st half */
    node *second;               /* Points to head node of 2nd half */
    node *f_ptr = head;         /* Fast pointer */
    node *s_ptr = head;         /* Slow pointer */
    node *prev = NULL;          /* Previous to slow pointer */
    bool ret = false;           /* Return value */

    while (f_ptr && f_ptr->next && f_ptr->next->next)
    {
        prev = s_ptr;
        s_ptr = s_ptr->next;
        f_ptr = f_ptr->next->next;
    }

    /* List with odd number of elements */
    if (!(f_ptr->next))
    {
        first = head;
        second = s_ptr->next;
        prev->next = NULL;
        s_ptr->next = NULL;
        /* Reverse the second half */
        second = reverse_list(&second);
        /* Compare the first & second half */
        ret = are_identical(first, second);
        /* Finally, construct the original list back */
        second = reverse_list(&second);
        prev->next = s_ptr; s_ptr->next = second;
        print_list(head);
    }
    /* List with even number of elements */
    else if (!(f_ptr->next->next))
    {
        first = head;
        second = s_ptr->next;
        s_ptr->next = NULL;
        /* Reverse the second half */
        second = reverse_list(&second);
        /* Compare the first & second half */
        ret = are_identical(first, second);
        /* Finally, construct the original list back */
        second = reverse_list(&second);
        s_ptr->next = second;
        print_list(head);
    }
    return ret;
}