Java经典面试题——手写快速排序和归并排序

题目链接:https://www.luogu.com.cn/problem/P1177
在这里插入图片描述

输入模板:

5
4 2 4 5 1

快速排序

技巧:交换数组中的两个位置

a[l] = a[l] + a[r] - (a[r] = a[l]);

稳定不稳定?:不稳定

注意找哨兵那里内循环的等于号不能漏,不然出不来循环了。因为如果数值都一样,那么l和r一直保持不变了

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[1000005];
        for(int i = 1; i<= n;i++)
            a[i] = scanner.nextInt();
        scanner.close();
        quickSort(a,1,n);
        for(int i=1;i<=n;i++){
            if(i==1) 
                System.out.print(a[i]);
            else
                System.out.print(" "+a[i]);
        }
        return ;
    }
    //数组的传递时通过引用进行传递的
    public static void quickSort(int[] a, int left, int right){
        //设置一个哨兵,分治排序,使得小于哨兵的所有节点都小于他,大于哨兵的所有
        //节点都大于他
        if(left>=right)
            return ; 
        int solder = partSort(a, left, right);
        quickSort(a, left, solder-1);
        quickSort(a, solder+1, right);
        return ;
    }
    public static int partSort(int[] a,int left,int right){
        int pivot=a[left];
		 while(left<right) {
			 //起初,一定要从右边指针开始,因为arr[low]的值已经扔给了pivot,arr[low]
			 //想象成无数字的空位
			 while(left<right&&pivot<=a[right])
				 --right;
			 //把比pivot的小的数扔到左边指针
			 //把arr[high]扔到arr[low]这个空位上
			 //然后,high位置可以想象成无数字的空位
			 a[left]=a[right];
			 while(left<right&&a[left]<=pivot)
				 ++left;
			 //把比pivot大的数扔到右边
			//把arr[low]扔到arr[high]这个空位上
			//然后,low位置可以想象成是无数字的空位
			 a[right]=a[left];
		 }
		 //此时low==high,return high也一样
		 a[left]=pivot;
		return left;
    }   
}

归并排序

归并比快排好写

import java.util.*;

public class Main {
    public static void main(String[] args) {
        //手写一个快排,分治排序
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] array = new int[n];
        for(int i = 0;i<=n-1;i++)
            array[i] = scanner.nextInt();
        QuickSort(array,0,n-1);
        for(int x:array)
            System.out.print(x+" ");
    }
    public static void QuickSort(int[] array,int left, int right){
        //System.out.println(left+" "+right);
        if(left>=right)
            return ;
        else{
            int mid = (left+right)/2;
            QuickSort(array, left, mid);
            QuickSort(array, mid+1, right);
            MergeArray(array,left,right,mid+1);
        }
        return ;
    }
    public static void MergeArray(int[] array,int left,int right,int mid){
        int[] temp = new int[array.length];
        int p = left,q = mid;
        for(int i=left;i<=right;i++){
            if(q>right||p<mid&&array[p]<array[q]){
                temp[i]=array[p];
                p++;
            }else{
                temp[i]=array[q];
                q++;
            }
        }
        for(int i=left;i<=right;i++){
            array[i] = temp[i];
        }
        return ;
    }
}

通过对比归并排序和快速排序,我们可以发现,归并排序和快速排序的区别在于

//快速排序
int solder = partSort(array, left, right);
QuickSort(array, left, solder-1);
QuickSort(array, solder+1, right);
//归并排序
QuickSort(array, left, mid);
QuickSort(array, mid+1, right);
MergeArray(array,left,right,mid+1);

一个的QuickSort在两次递归之前,一个在两次递归之后,因为归并是先拆后再合并,而快速排序我们需要知道哨兵的位置,所以需要先进行局部排序找到哨兵。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/267174.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【STM32】I2C通信

基本的任务是&#xff1a;通过通信线&#xff0c;实现单片机读写外挂模块寄存器的功能。其中至少要实现在指定位置写寄存器和在指定的位置读寄存器这两个功能。 异步时序的优点&#xff1a;省一根时钟线&#xff0c;节约资源&#xff1b;缺点&#xff1a;对事件要求严格&#…

VSCode运行时弹出powershell

问题 安装好了vscode并且装上code runner插件后&#xff0c;运行代码时总是弹出powershell,而不是在vscode底部终端 显示运行结果。 解决方法 打开系统cmd ,在窗口顶部条右击打开属性&#xff0c;把最下面的旧版控制台选项取消&#xff0c;即可

关于JVM的垃圾回收GC的一些记录

目录 一、JVM内存区域划分 二、从一个基本问题开始引入垃圾回收 三、GC作用的区域 三、如何确定一个对象是否可以被当成垃圾进行回收 &#xff08;1&#xff09;引用计数法 &#xff08;2&#xff09;可达性分析算法 &#xff08;3&#xff09;引用的类型 &#xff08;3…

Netty Review - Netty自动重连机制揭秘:原理与最佳实践

文章目录 概述Pre客户端自动重连CodeServerClient (重点) 测试启动自动重连运行过程中断链后的自动重连 概述 Pre Netty Review - 深入探讨Netty的心跳检测机制&#xff1a;原理、实战、IdleStateHandler源码分析 客户端自动重连 自动重连是一个用于提高网络应用稳定性和可靠…

OpenSource - SCM服务管理平台

文章目录 官方网址文档下载版本功能解决了哪些问题使用对象优势Linxu版本scm-dev deb服务列表 Windows版本scm-dev 服务列表scm-all 服务列表scm-jdk 服务列表scm-springboot 精简版本服务列表scm-springboot 服务列表scm-tomcat 服务列表 SCM 截图 官方网址 https://scm.chus…

如何更好的去理解源码

前言 这篇文章我准备来聊一聊如何去阅读开源项目的源码。 在聊如何去阅读源码之前&#xff0c;先来简单说一下为什么要去阅读源码&#xff0c;大致可分为以下几点原因&#xff1a; 最直接的原因&#xff0c;就是面试需要&#xff0c;面试喜欢问源码&#xff0c;读完源码才可以…

代码随想录-刷题第三十六天

435. 无重叠区间 题目链接&#xff1a;435. 无重叠区间 思路&#xff1a;本题与452. 用最少数量的箭引爆气球非常像&#xff0c;弓箭的数量就相当于是非交叉区间的数量&#xff0c;只要把弓箭那道题目代码里射爆气球的判断条件加个等号&#xff08;认为[0&#xff0c;1][1&am…

Kafka集群架构服务端核心概念

目录 Kafka集群选举 controller选举机制 Leader partition选举 leader partition自平衡 partition故障恢复机制 follower故障 leader故障 HW一致性保障 HW同步过程 Epoch Kafka集群选举 1. 在多个broker中, 需要选举出一个broker, 担任controller. 由controller来管理…

深入理解 Git 分支管理:提升团队协作与开发效率

目录 前言1 什么是分支2 分支的好处2.1 并行开发的支持2.2 独立性与隔离性2.3 灵活的版本控制2.4 提高安全性和代码质量2.5 项目历史的清晰记录 3 Git 分支操作命令3.1 git branch -v3.2 git branch 分支名称3.3 git checkout 分支名称3.4 git merge 分支名称3.5 git rebase 分…

RabbitMQ的概念与使用

什么是MQ&#xff1f; MQ 是消息队列&#xff08;Message Queue&#xff09;的简称。消息队列是一种应用程序间通信的方式&#xff0c;用于在不同的应用程序之间传递消息。它通过解耦发送者和接收者之间的直接依赖关系&#xff0c;提供了一种异步、可靠的消息传递机制。 什么是…

爬虫是什么?起什么作用?

【爬虫】 如果把互联网比作一张大的蜘蛛网&#xff0c;数据便是放于蜘蛛网的各个节点&#xff0c;而爬虫就是一只小蜘蛛&#xff0c;沿着网络抓取自己得猎物&#xff08;数据&#xff09;。这种解释可能更容易理解&#xff0c;官网的&#xff0c;就是下面这个。 爬虫是一种自动…

红日靶场-2

目录 前言 外网渗透 外网渗透打点 1、arp探测 2、nmap探测 3、nikto探测 4、gobuster目录探测 WebLogic 10.3.6.0 1、版本信息 2、WeblogicScan扫描 3、漏洞利用 4、哥斯拉连接 内网渗透 MSF上线 1、反弹连接 2、内网扫描 3、frpc内网穿透 4、ms17-010 5、ge…

第十三章 常用类(包装类和 String 相关类)

一、包装类 1. 包装类的分类 &#xff08;1&#xff09;针对八种基本数据类型相应的引用类型—包装类 &#xff08;2&#xff09;有了类的特点&#xff0c;就可以调用类中的方法。 2. 包装类和基本数据类型的转换 &#xff08;1&#xff09;jdk5 前的手动装箱和拆箱方式 publ…

Unity预设体

目录 预设体是什么&#xff1f; 如何创建预设体&#xff1f; 如何修改预设体&#xff1f; 如何删除预设体&#xff1f; 预设体是什么&#xff1f; Unity中的预设体&#xff08;Prefab&#xff09;是一种可重复使用的游戏对象模板。它允许开发者创建一个或多个游戏对象&…

模型评估系列:回归模型的评估指标介绍和代码实践

文章目录 1. 简介2. 回归评估指标2.1 平均绝对误差&#xff08;MAE&#xff09;2.2 均方误差&#xff08;MSE&#xff09;2.3 均方根误差&#xff08;RMSE&#xff09;2.4 R平方&#xff08;决定系数&#xff09;2.5 调整后的R平方2.6 交叉验证的R22.7 回归评估指标 - 结论 3 设…

OpenCV-10mat的深浅拷贝

一.Mat介绍 mat是OpenCV是在C语言用来表达图像数据的一种数据结构&#xff0c;在Python转换为numpy的ndarray. mat是由header和date组成&#xff0c;header中记录了图片的维数、大小、数据类型等信息. 例如&#xff1a;cv2.imshow&#xff08;winname&#xff0c; mat&#…

基于Boosting的力扣题目建模分析

基于Boosting的力扣题目建模分析 1 背景介绍2 数据说明3 描述性分析3.1 分类问题描述性分析3.2 回归问题描述性分析 4 建模分析4.1 Boosting概述4.2 AdaBoost算法4.2.1 算法概述4.2.2 算法实现 4.3 提升树算法4.3.1 算法概述4.3.2 算法实现 5 总结 1 背景介绍 随着大数据、人工…

2024 年全球顶级的 4 款 PDF 转换器软件

PDF 是一种广泛使用的共享文档和文件的格式。但是&#xff0c;有时您可能需要将 PDF 文件转换为其他格式&#xff08;例如 Word 或 Excel&#xff09;&#xff0c;以便编辑或操作内容。这就是 PDF 转换器软件派上用场的地方。 有许多 PDF 转换器软件可供选择&#xff0c;有免费…

day06

文章目录 一、流程控制1. 作用2. 分类1&#xff09;顺序结构2&#xff09;选择结构1. if语句2. switch语句 3&#xff09;循环结构 二、函数1. 作用2. 语法3. 使用4. 匿名函数5. 作用域 一、流程控制 1. 作用 控制代码的执行顺序 2. 分类 1&#xff09;顺序结构 从上到下依…

openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据

文章目录 openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据170.1 前提条件170.2 操作步骤 openGauss学习笔记-170 openGauss 数据库运维-备份与恢复-导入数据-更新表中数据-使用合并方式更新和插入数据 在用户需要将…