链表排序(自己鼓捣出一种递归建表)

news/2024/5/3 20:52:57 标签: 链表, 数据结构

递归建表

是不是很优雅!

struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
 };

ListNode* Create(int n) {
    if(!n)  return NULL;
    int num;
    cin >> num;
    auto p = new ListNode(num, Create(n - 1));
    return p;
}

插入排序

自己鼓捣的,不知道叫什么名字,有点插入的味道,姑且叫做插入排序吧

核心思路:

=> 新开一个哨兵结点dummy,后面接有序链表

待排序链表记录当前结点(p)及其后驱结点(last),然后断开两者联系(p->next = NULL);

接着,将p插入到dummy后面的结点中的合适位置(通过while+ if判断);

p = last,不断迭代。

List DSortList(List head) {
    if(!head || !head->next) return head;
    List last = head->next;
    head->next = NULL;
    List dummy = (List)malloc(sizeof(Node));
    dummy->aver = INT_MAX;
    dummy->next = head;
    List p = last;
    while(p) {
        last = p->next;
        p->next = NULL;
        List temp = dummy;
        while(temp) {
            if(temp->next == NULL || (temp->aver >= p->aver && temp->next->aver <= p->aver) ) {
                p->next = temp->next;
                temp->next = p;
                break;
            }
            temp = temp->next;
        }
        p = last;
    }
    return dummy->next;
}

leetcode上看到的比较优雅的解法:

ListNode* insertionSortList(ListNode* head) {
        auto dummy = new ListNode(-1, NULL);
        auto p = head;
        while(p) {
            auto cur = dummy;
            while(cur->next && cur->next->val <= p->val) cur = cur->next;
            auto next = p->next;
            p->next = cur->next;
            cur->next = p;
            p = next;
        }
        return dummy->next;
    }

本质和我的思路一样,但是代码更加短小精悍,值得推荐

归并排序

归并排序其实是链表排序的主流方法(时间复杂度是O(nlogn)。 归并主要分为分割合并两大部分,入栈的时候分割,出栈的时候合并,这也是归并常常采用递归实现的原因

class Merge{
public:
    ListNode* sort(ListNode* head) {
        if(!head || !head->next) return head;
        return mergeSort(head);
    }

private:
    ListNode* mergeSort(ListNode* head) {
        if(!head || !head->next) return head;
        auto slow = head, fast = head->next;
        while(fast && fast->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        auto rightHead = slow->next;
//        记得断开左右两个链表的联系
        slow->next = NULL;
        auto left = mergeSort(head);
        auto right = mergeSort(rightHead);
        return merge(left, right);
    }

    ListNode* merge(ListNode* p1, ListNode* p2) {
        auto dummy = new ListNode(-1, NULL);
        auto p = dummy;
        while(p1 && p2) {
            if(p1->val < p2->val) {
                p->next = p1;
                p1 = p1->next;
            }else {
                p->next = p2;
                p2 = p2->next;
            }
            p = p->next;
        }
        p->next = p1 ? p1 : p2;
        return dummy->next;
    }
};


http://www.niftyadmin.cn/n/409374.html

相关文章

外观设计模式解读

目录 问题引进 传统方式解决影院管理 外观模式基本介绍 概念 外观模式原理类图 分类外观模式的角色 外观模式解决影院管理 传统方式解决影院管理说明 外观模式应用实例 外观模式的注意事项和细节 s统的内部细节 > 外观模式 外观模式基本介绍 概念 1) 外观模式&…

让我们彻底了解Maven(二)--- Maven私服的搭建

首先我们为什么需要搭建Maven私服&#xff0c;一切技术来源于解决需求&#xff0c;因为我们在实际开发中&#xff0c;当我们研发出来一个公共组件&#xff0c;为了能让别的业务开发组用上&#xff0c;则搭建一个远程仓库很有必要&#xff0c;写完公用组件后&#xff0c;直接发布…

初学者应该怎么学git-下

初学者应该怎么学git-下 Git 文件管理 文件四种状态 ● 版本控制就是对文件的版本控制&#xff0c;在Git 管理中&#xff0c;文件被统一管理&#xff0c;有四个状态 Untracked: 未跟踪, 此文件在文件夹中, 但并没有加入到git 库, 不参与版本控制. 通过git add 状态变为Stage…

vue中的计算属性和侦听器

目录 计算属性使用计算属性只读计算属性可写计算属性 计算属性的缓存 侦听器使用侦听器侦听不同的数据源深度侦听直接给 watch() 传入一个响应式对象使用deep 选项&#xff0c;强制转成深层侦听器 立即侦听watchEffect()watch 和 watchEffect的区别 计算属性和侦听器的异同点相…

【webFlux】zipWithIterable()判断是否有空值以及未与iterable 匹配时设置默认值

判断是否有空值 在使用zipWithIterable()方法时&#xff0c;如果Iterable集合为空&#xff0c;那么zipWithIterable()方法会返回一个空的Flux流。如果Flux流为空&#xff0c;那么zipWithIterable()方法也会返回一个空的Flux流。 如果Iterable集合中有null元素&#xff0c;那么…

C++基础(三) —— STL组件

文章目录 一、C STL standard template libaray 标准模板库 1.顺序容器 vector&#xff1a; 底层数据结构&#xff1a;动态开辟的数组 扩容方式&#xff1a;每次以原来空间大小的2倍进行扩容 具体过程&#xff1a; 当需要在 std::vector 中插入元素时&#xff0c;如果当前容量…

网络通信 --- HTTP 协议初识

目录 &#x1f332;一、HTTP 协议是什么 &#x1f333;二、HTTP协议格式 &#x1f9aa;1.抓包工具的使用(以 Fiddler 为例) &#x1f363;2. 抓包工具的原理 (以 Fiddler 为例) &#x1f364;3. 抓包结果 &#x1f365;① HTTP 请求(request) &#x1f96e;②HTTP响应(re…

【科技素养题】少儿编程 蓝桥杯青少组科技素养题真题及解析第20套

少儿编程 蓝桥杯青少组科技素养题真题及解析第20套 1、“唐纳德特朗普 (Donald Trump) 曾经是美国总统”是一个 (),“特朗普关于新冠肺炎疫情的不实言论”是一个 ()。 A、事实;事实 B、观点;事实 C、观点;观点 D、事实;观点 答案:D 考点分析:主要考查小朋友们对时事的…