首页 > 其他分享 >单链表快速排序

单链表快速排序

时间:2023-07-18 10:12:34浏览次数:47  
标签:head 单链 val next 链表 right 排序 快速 left

title: 单链表快速排序
date: 2023-07-18 09:06:37
tags:
- c/c++
categories:
- 算法
- 笔试
top:

单链表快速排序

题目来自acwing

题目(点击跳转)

给定一个单链表,请使用快速排序算法对其排序。

要求:期望平均时间复杂度为 O(nlogn),期望额外空间复杂度为 O(logn)。

思考题: 如果只能改变链表结构,不能修改每个节点的val值该如何做呢?

数据范围

链表中的所有数大小均在 int范围内,链表长度在 [0,10000]。
本题数据完全随机生成。

输入样例:

[5, 3, 2]

输出样例:

[2, 3, 5]

思路:

单链表的快排比数组的快排要好一点,边界问题不用处理。

  • 进入排序算法,先判断链表是否有值,如果没有值或者只有一个值,直接return即可
  • 申请三个链表头节点分别是left, mid, right,用来将链表进行排序,申请三个尾结点ltail, mtail, rtail,初始化为每个节点本身,创建一个val,即每次排序选择的一个标杆。
  • 遍历单链表(这里循环结束之后要把链表尾部置空,让链表知道结束的位置)
    • 如果当前节点的值小于val就将节点连入left链表,即ltail->next = p; ltail = p;,这里尾结点next赋值之后要向后移动一位,即指向链表的尾部。
    • 如果当前节点的值等于val就将节点连入mid链表,即mtail->next = p; mtail = p;
    • 如果当前节点的值大于val就将节点连入right链表,即rtail->next = p; rtail = p;
  • 处理完之后可以得到三个链表,这是如果left和right两个链表有序之后,将三个链表连接一下就是最后的结果。
    • 递归处理left链表,left->next即链表的值
    • 递归处理right链表,right->next即链表的值
  • 这里实现一个get_tail()方法,获取传入链表的尾结点。
  • 最后将三个链表连接到一起即可。
    • 这里有一个细节是,mid链表可能没有值,所以连接完mid之后接着去找到left的尾结点去连接right链表。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* get_tail(ListNode* head){
        while(head->next) head = head->next;
        return head;
    }
    ListNode* quickSortList(ListNode* head) {
        if(!head || !head->next) return head;
        auto left = new ListNode(-1), mid = new ListNode(-1), right = new ListNode(-1);
        auto ltail = left, mtail = mid, rtail = right;
        int val = head->val;
        for(auto p = head; p; p = p->next) {
            if(p->val < val) {ltail->next = p; ltail = p;}
            else if (p->val == val) {mtail->next = p; mtail = p;}
            else {rtail->next = p; rtail = p;}
        }
        ltail->next = mtail->next = rtail->next = NULL;
        left->next = quickSortList(left->next);
        right->next = quickSortList(right->next);
        get_tail(left)->next = mid->next;
        get_tail(left)->next = right->next;
        return left->next;
    }
};

标签:head,单链,val,next,链表,right,排序,快速,left
From: https://www.cnblogs.com/hhhhuaz/p/17562034.html

相关文章

  • 数据结构练习笔记——删除单链表中相同元素
    删除单链表中相同元素【问题描述】单链表中存放了若干整数,请删除相同整数。【输入形式】单链表【输出形式】删除相同整数后的单链表【样例输入】11123【样例输出】123【样例说明】递增的形式输入数据,允许相同元素#include<stdlib.h>#include<iostream>usingname......
  • 浅析vue3中如何使用动态组件、如何快速理解Vue3的 toRaw和markRaw、ref与shallowRef、
    一、Vue3中使用component:is加载动态组件1、不使用setup语法糖,这种方式和vue2差不多,is可以是个字符串2、使用setup语法糖,这时候的is如果使用字符串就会加载不出来,得使用组件实例<componentclass="task-box":is="componentObj[route.params.type]":info="taskInfo"></co......
  • C/C++八大排序
    排序排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。按照难易程度排序,八大排序算法可以从简单到复杂依次排列如下:冒泡排序(BubbleSort)选择排序(SelectionSort)插入排序(Inser......
  • weblogic快速安装
    #####################################################weblogic快速安装#######################1、使用root用户创建目录/opt/weblogic并授权创建目录:mkdir/opt/weblogicchmod777/opt/weblogic//生产环境适量而设授权用户:chown-Rweblogic:weblogic/opt/weblogic进......
  • 拓扑排序算法相关的知识点总结
    拓扑排序算法相关的知识点总结拓扑排序算法是一种对有向无环图(DAG)进行排序的方法,它可以将图中的所有顶点排成一个线性序列,使得对于任意一对顶点u和v,如果存在一条从u到v的有向边,那么u在序列中必然出现在v之前。拓扑排序算法可以用来解决一些依赖关系的问题,例如课程安排、工程进度......
  • GO语言调试利器dlv快速上手
    GO语言调试利器dlv快速上手 golang安装 tar-xvfgo1.15.2.linux-arm64.tar.gz -C /usr/local/go[root@centos7~]#ls/usr/local/gogo[root@centos7~]#ls/usr/local/go/go/apiAUTHORSbinCONTRIBUTING.mdCONTRIBUTORSdocfavicon.icolibL......
  • Rust 学习笔记:快速上手篇
    Rust学习笔记:快速上手篇这篇学习笔记将用于记录本人在快速上手Rust编程语言时所记录的学习心得与代码实例。为此,我会在本笔记库项目的Programming/LanguageStudy/目录下创建一个名为Rust的目录,并在该目录下设置以下两个子目录:QuickStart目录用于存放Markdown格式的笔记。......
  • RESTful快速开发
        ......
  • NO35、数组中的逆排序(建议再刷)
    35、数组中的逆排序很好的题目,建议再刷在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。即输出P%1000000007输入描述:题目保证输入的数组中没有的相同的数字数据范......
  • 手写死锁&&死锁的原因是什么?如何快速定位死锁?如何避免死锁
    一个简单的死锁案例:packagemylock;publicclassDeadlockExample{publicstaticvoidmain(String[]args){finalObjectresource1=newObject();finalObjectresource2=newObject();//线程1占用资源1,等待资源2Threadth......