📌  相关文章
📜  C程序检查单链表是否为回文(1)

📅  最后修改于: 2023-12-03 15:00:13.249000             🧑  作者: Mango

C程序检查单链表是否为回文

回文是指一串字符串、数字或其他序列在顺读和倒读时都是一样的,比如“level”、“12321”等。这里我们来讨论如何使用C语言检查单链表是否为回文。

实现思路

单链表是由一个一个节点组成的,我们可以将链表的前半部分倒序,然后和后半部分比较,如果相同则为回文。为了达到这个目的,我们需要实现以下四个步骤:

  1. 找到链表的中间节点。
  2. 将链表的前半部分倒序。
  3. 比较前半部分和后半部分是否相同。
  4. 将链表的前半部分还原为原来的顺序。
代码实现
/* 定义单链表节点的结构体 */
typedef struct ListNode {
    int val;  // 节点的值
    struct ListNode* next;  // 指向下一个节点的指针
} ListNode;

/* 获取链表的长度 */
int getListLength(ListNode* head) {
    int len = 0;
    while (head != NULL) {
        len++;
        head = head->next;
    }
    return len;
}

/* 反转链表 */
ListNode* reverseList(ListNode* head) {
    ListNode* prev = NULL;
    ListNode* curr = head;
    while (curr != NULL) {
        ListNode* next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }
    return prev;
}

/* 比较两个链表是否相同 */
bool compareList(ListNode* l1, ListNode* l2) {
    while (l1 != NULL && l2 != NULL) {
        if (l1->val != l2->val) {
            return false;
        }
        l1 = l1->next;
        l2 = l2->next;
    }
    return true;
}

/* 检查单链表是否为回文 */
bool isPalindrome(ListNode* head) {
    /* 获取链表的长度 */
    int len = getListLength(head);
    if (len == 0 || len == 1) {
        /* 链表为空或只有一个节点时为回文 */
        return true;
    }

    /* 找到链表的中间节点 */
    ListNode* slow = head;
    ListNode* fast = head;
    while (fast != NULL && fast->next != NULL) {
        slow = slow->next;
        fast = fast->next->next;
    }

    /* 反转链表的前半部分 */
    ListNode* prev = NULL;
    ListNode* curr = head;
    for (int i = 0; i < len / 2; i++) {
        ListNode* next = curr->next;
        curr->next = prev;
        prev = curr;
        curr = next;
    }

    /* 比较前半部分和后半部分是否相同 */
    bool result = compareList(prev, slow);

    /* 将链表的前半部分还原为原来的顺序 */
    reverseList(prev);
    return result;
}
测试示例

以下是一些测试示例:

测试用例1
ListNode* head = NULL;
if (isPalindrome(head)) {
    printf("该链表为回文");
} else {
    printf("该链表不为回文");
}

输出:

该链表为回文
测试用例2
ListNode node1 = { 1, NULL };
ListNode node2 = { 2, &node1 };
ListNode node3 = { 3, &node2 };
ListNode node4 = { 2, &node3 };
ListNode node5 = { 1, &node4 };
if (isPalindrome(&node5)) {
    printf("该链表为回文");
} else {
    printf("该链表不为回文");
}

输出:

该链表为回文
测试用例3
ListNode node1 = { 1, NULL };
ListNode node2 = { 2, &node1 };
ListNode node3 = { 3, &node2 };
ListNode node4 = { 4, &node3 };
ListNode node5 = { 5, &node4 };
if (isPalindrome(&node5)) {
    printf("该链表为回文");
} else {
    printf("该链表不为回文");
}

输出:

该链表不为回文
总结

以上就是使用C语言检查单链表是否为回文的实现思路和代码实现。通过将链表的前半部分倒序,我们可以很方便地检查链表是否为回文。