当前位置: 首页 > article >正文

链表排序--(奇数位是升序,偶数位是降序)

题目描述

对一个单链表进行排序,但这个链表有一个特殊的结构:

奇数位是升序:链表中位于奇数位置的节点是按升序排列的。例如,如果链表的第1个节点的值是1,第3个节点的值是3,第5个节点的值是5,那么这些值是按升序排列的。

偶数位是降序:链表中位于偶数位置的节点是按降序排列的。例如,如果链表的第2个节点的值是8,第4个节点的值是6,第6个节点的值是4,那么这些值是按降序排列的。

示例

假设我们有一个链表如下:

1 -> 8 -> 3 -> 6 -> 5 -> 4 -> nullptr

● 奇数位:第1个节点是1,第3个节点是3,第5个节点是5。这些节点的值是 1, 3, 5,它们是升序的。

● 偶数位:第2个节点是8,第4个节点是6,第6个节点是4。这些节点的值是 8, 6, 4,它们是降序的。

排序目标

要将这个链表重新排列成一个完全升序的链表

思路分析

  1. 分离链表:首先将链表分成两个链表,一个包含奇数位节点,另一个包含偶数位节点。

  2. 反转偶数位链表:由于偶数位是降序的,我们可以将偶数位链表反转,使其变为升序。

  3. 合并链表:将两个升序的链表合并成一个完全升序的链表。

分离链表

反转偶数位链表

合并两个有序链表

最终排序结果

对于上面的示例链表,排序后的链表应该是:

1 -> 3 -> 4 -> 5 -> 6 -> 8 -> nullptr

这个链表中的所有节点都是按升序排列的。

完整代码

#include <iostream>
using namespace std;

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

// 分离链表为奇数位和偶数位
pair<ListNode*, ListNode*> splitList(ListNode* head) {
    ListNode* oddHead = nullptr;
    ListNode* evenHead = nullptr;
    ListNode* oddTail = nullptr;
    ListNode* evenTail = nullptr;
    int index = 1;

    while (head) {
        if (index % 2 == 1) { // 奇数位
            if (!oddHead) {
                oddHead = head;
                oddTail = head;
            }
            else {
                oddTail->next = head;
                oddTail = oddTail->next;
            }
        }
        else { // 偶数位
            if (!evenHead) {
                evenHead = head;
                evenTail = head;
            }
            else {
                evenTail->next = head;
                evenTail = evenTail->next;
            }
        }
        head = head->next;
        index++;
    }

    if (oddTail) oddTail->next = nullptr;
    if (evenTail) evenTail->next = nullptr;

    return { oddHead, evenHead };
}

// 反转链表
ListNode* reverseList(ListNode* head) {
    auto newhead = new ListNode(0);
    auto p = head;
    while (p) {
        auto q = p->next;
        p->next = newhead->next;
        newhead->next = p;
        p = q;
    }
    return newhead->next;
}

// 合并两个升序链表
ListNode* mergeLists(ListNode* l1, ListNode* l2) {
    auto newhead = new ListNode(0);
    auto tail = newhead;

    while (l1 && l2) {
        if (l1->val < l2->val) {
            tail->next = l1;
            l1 = l1->next;
        }
        else {
            tail->next = l2;
            l2 = l2->next;
        }
        tail = tail->next;
    }

    tail->next = l1 ? l1 : l2;

    return newhead->next;
}

// 主函数:对链表进行排序
ListNode* sortLinkedList(ListNode* head) {
    if (!head || !head->next) return head;

    // 保存 splitList 的结果
    pair<ListNode*, ListNode*> splitResult = splitList(head);
    ListNode* oddHead = splitResult.first;   // 提取奇数位链表
    ListNode* evenHead = splitResult.second; // 提取偶数位链表
   

    // 反转偶数位链表
    evenHead = reverseList(evenHead);

    // 合并两个升序链表
    return mergeLists(oddHead, evenHead);
}

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

// 测试代码
int main() {
    ListNode* head = new ListNode(1);
    head->next = new ListNode(8);
    head->next->next = new ListNode(3);
    head->next->next->next = new ListNode(6);
    head->next->next->next->next = new ListNode(5);
    head->next->next->next->next->next = new ListNode(4);

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

    ListNode* sortedHead = sortLinkedList(head);

    cout << "Sorted List: ";
    printList(sortedHead);

    return 0;
}

运行结果


http://www.kler.cn/a/521876.html

相关文章:

  • deepseek-r1 本地部署
  • 2218. 从栈中取出 K 个硬币的最大面值和
  • 初始JavaEE篇 —— Spring Web MVC入门(上)
  • 【设计模式-行为型】访问者模式
  • Linux初识——基本指令(2)
  • 蓝桥杯模拟算法:蛇形方阵
  • 算法-遍历分发糖果
  • 解码大数据的四个V:体积、速度、种类与真实性
  • SpringMVC的参数处理
  • c语言中mysql_query的概念和使用案例
  • Niagara学习笔记
  • 解决Oracle SQL语句性能问题(10.5)——常用Hint及语法(7)(其他Hint)
  • 【linux】Linux 常见目录特性、权限和功能
  • LockSupport概述、阻塞方法park、唤醒方法unpark(thread)、解决的痛点、带来的面试题
  • Firewalld 防火墙
  • Python的那些事第三篇:Python编程的“调味料”与“交流术”运算符与输入输出
  • 读书笔记--分布式服务架构对比及优势
  • 基于SpringBoot的志愿者招募管理系统
  • 目标跟踪之sort算法(3)
  • [免费]基于Python的Django博客系统【论文+源码+SQL脚本】
  • Python3 【函数】项目实战:5 个新颖的学习案例
  • 从0到1:.NET Core微服务的Docker容器奇幻冒险
  • springboot 动态线程池
  • 省级金融发展水平数据(2000-2022年)-社科数据
  • git困扰的问题
  • C++标准线程库实现优雅退出的方式