C++ | 链表奇偶重排

一、问题描述

给定一个单链表,要求将链表中的节点按照奇偶位置重新排列。具体规则如下:

  • 奇数位置的节点:1、3、5、...(从1开始计数)

  • 偶数位置的节点:2、4、6、...(从1开始计数)

  • 重排后:所有奇数位置的节点按原顺序排列在前面,所有偶数位置的节点按原顺序排列在后面。

示例

  • 输入1 -> 2 -> 3 -> 4 -> 5 -> NULL

  • 输出1 -> 3 -> 5 -> 2 -> 4 -> NULL

  • 输入2 -> 1 -> 3 -> 5 -> 6 -> 4 -> 7 -> NULL

  • 输出2 -> 3 -> 6 -> 7 -> 1 -> 5 -> 4 -> NULL

二、解题思路

  1. 初始化两个链表:一个用于存储奇数位置的节点,另一个用于存储偶数位置的节点。

  2. 遍历原链表:通过一个指针遍历原链表,根据节点的位置将其分别连接到奇数链表和偶数链表。

  3. 合并两个链表:将偶数链表连接到奇数链表的末尾。

三、代码实现

时间复杂度: O(n)。

空间复杂度: O(1)。

#include 
using namespace std;

// 定义链表节点
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(nullptr) {}
};

// 打印链表
void printList(ListNode* head) {
    while (head) {
        cout << head->val << " -> ";
        head = head->next;
    }
    cout << "NULL" << endl;
}

// 奇偶重排链表
ListNode* oddEvenList(ListNode* head) {
    if (!head || !head->next) {
        return head; // 如果链表为空或只有一个节点,直接返回
    }

    ListNode* odd = head; // 奇数链表头
    ListNode* even = head->next; // 偶数链表头
    ListNode* evenHead = even; // 保存偶数链表的头节点

    while (even && even->next) {
        odd->next = even->next; // 将奇数节点连接到奇数链表
        odd = odd->next; // 移动奇数指针

        even->next = odd->next; // 将偶数节点连接到偶数链表
        even = even->next; // 移动偶数指针
    }

    odd->next = evenHead; // 将偶数链表连接到奇数链表末尾
    return head; // 返回重排后的链表头
}

int main() {
    // 创建链表:1 -> 2 -> 3 -> 4 -> 5 -> NULL
    ListNode* head = new ListNode(1);
    head->next = new ListNode(2);
    head->next->next = new ListNode(3);
    head->next->next->next = new ListNode(4);
    head->next->next->next->next = new ListNode(5);

    cout << "Original list: ";
    printList(head);

    head = oddEvenList(head);

    cout << "Reordered list: ";
    printList(head);

    return 0;
}

你可能感兴趣的:(C++,手撕算法,链表,算法,数据结构,c++)