常见排序算法Java实现

news/2025/10/28 23:22:29/文章来源:https://www.cnblogs.com/18sui/p/19172931

/**

  • 常见排序算法汇总
    */
    public class SortAlgorithms {

    /**

    • 冒泡排序(Bubble Sort)
    • 思想:相邻元素两两比较,大的往后沉。
    • 时间复杂度:O(n^2)
    • 稳定性:稳定
      */
      public static void bubbleSort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
      for (int j = 0; j < arr.length - 1 - i; j++) {
      // 若前一个数比后一个大,则交换
      if (arr[j] > arr[j + 1]) {
      swap(arr, j, j + 1);
      }
      }
      }
      }

    /**

    • 选择排序(Selection Sort)
    • 思想:每轮选择最小(或最大)的元素放到前面。
    • 时间复杂度:O(n^2)
    • 稳定性:不稳定
      */
      public static void selectionSort(int[] arr) {
      for (int i = 0; i < arr.length - 1; i++) {
      int minIndex = i;
      // 找到未排序部分的最小值
      for (int j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[minIndex]) {
      minIndex = j;
      }
      }
      // 将最小值放到当前轮的开头
      swap(arr, i, minIndex);
      }
      }

    /**

    • 插入排序(Insertion Sort)
    • 思想:将元素插入到前面已排序部分的正确位置。
    • 时间复杂度:O(n^2)
    • 稳定性:稳定
      */
      public static void insertionSort(int[] arr) {
      for (int i = 1; i < arr.length; i++) {
      int key = arr[i]; // 当前要插入的元素
      int j = i - 1;
      // 从后往前比较,找到插入位置
      while (j >= 0 && arr[j] > key) {
      arr[j + 1] = arr[j]; // 向后移动
      j--;
      }
      arr[j + 1] = key; // 插入
      }
      }

    /**

    • 希尔排序(Shell Sort)
    • 思想:将序列分为若干子序列进行插入排序,逐步减小间隔。
    • 时间复杂度:O(n log n)
    • 稳定性:不稳定
      */
      public static void shellSort(int[] arr) {
      // gap为步长,每轮缩小一半
      for (int gap = arr.length / 2; gap > 0; gap /= 2) {
      for (int i = gap; i < arr.length; i++) {
      int temp = arr[i];
      int j = i;
      // 按gap间隔进行插入排序
      while (j >= gap && arr[j - gap] > temp) {
      arr[j] = arr[j - gap];
      j -= gap;
      }
      arr[j] = temp;
      }
      }
      }

    /**

    • 归并排序(Merge Sort)
    • 思想:分治法,将数组分为两半,分别排序后再合并。
    • 时间复杂度:O(n log n)
    • 稳定性:稳定
      */
      public static void mergeSort(int[] arr) {
      mergeSortHelper(arr, 0, arr.length - 1);
      }

    private static void mergeSortHelper(int[] arr, int left, int right) {
    if (left >= right) return; // 递归终止条件
    int mid = (left + right) / 2;
    mergeSortHelper(arr, left, mid); // 排序左半部分
    mergeSortHelper(arr, mid + 1, right); // 排序右半部分
    merge(arr, left, mid, right); // 合并
    }

    // 合并两个有序子数组
    private static void merge(int[] arr, int left, int mid, int right) {
    int[] temp = new int[right - left + 1];
    int i = left, j = mid + 1, k = 0;

     // 合并过程:按顺序比较左右两边元素while (i <= mid && j <= right) {temp[k++] = arr[i] <= arr[j] ? arr[i++] : arr[j++];}// 将剩余元素依次拷贝while (i <= mid) temp[k++] = arr[i++];while (j <= right) temp[k++] = arr[j++];// 拷贝回原数组for (int t = 0; t < temp.length; t++) {arr[left + t] = temp[t];}
    

    }

    /**

    • 快速排序(Quick Sort)
    • 思想:分治法,选取一个“基准”,小的放左边,大的放右边。
    • 时间复杂度:平均O(n log n),最坏O(n^2)
    • 稳定性:不稳定
      */
      public static void quickSort(int[] arr) {
      quickSortHelper(arr, 0, arr.length - 1);
      }

    private static void quickSortHelper(int[] arr, int left, int right) {
    if (left >= right) return;
    int pivot = arr[left]; // 选取第一个元素为基准
    int i = left, j = right;

     // 分区过程while (i < j) {while (i < j && arr[j] >= pivot) j--; // 从右往左找小于pivot的数while (i < j && arr[i] <= pivot) i++; // 从左往右找大于pivot的数if (i < j) swap(arr, i, j);}// 将基准放到正确位置swap(arr, left, i);// 递归左右子序列quickSortHelper(arr, left, i - 1);quickSortHelper(arr, i + 1, right);
    

    }

    /**

    • 堆排序(Heap Sort)

    • 思想:利用堆结构(最大堆)来排序。

    • 时间复杂度:O(n log n)

    • 稳定性:不稳定
      */
      public static void heapSort(int[] arr) {
      int n = arr.length;

      // 1. 构建最大堆(从最后一个非叶子节点开始)
      for (int i = n / 2 - 1; i >= 0; i--) {
      heapify(arr, n, i);
      }

      // 2. 取出堆顶元素放到数组末尾
      for (int i = n - 1; i > 0; i--) {
      swap(arr, 0, i); // 交换堆顶与末尾元素
      heapify(arr, i, 0); // 重新调整堆
      }
      }

    // 调整堆,使其满足最大堆性质
    private static void heapify(int[] arr, int n, int i) {
    int largest = i; // 假设当前节点最大
    int left = 2 * i + 1; // 左子节点
    int right = 2 * i + 2; // 右子节点

     // 找出最大值的节点if (left < n && arr[left] > arr[largest]) largest = left;if (right < n && arr[right] > arr[largest]) largest = right;// 如果最大值不是当前节点,则交换并递归调整if (largest != i) {swap(arr, i, largest);heapify(arr, n, largest);}
    

    }

    /**

    • 工具函数:交换数组中的两个元素
      */
      private static void swap(int[] arr, int i, int j) {
      int temp = arr[i];
      arr[i] = arr[j];
      arr[j] = temp;
      }

    /**

    • 🧪 测试主函数
      */
      public static void main(String[] args) {
      int[] arr = {5, 3, 8, 4, 2, 7, 1, 6};

      System.out.println("原始数组:");
      printArray(arr);

      // 测试不同排序算法
      quickSort(arr); // 可替换为 bubbleSort(arr)、mergeSort(arr) 等

      System.out.println("排序后:");
      printArray(arr);
      }

    /**

    • 辅助打印函数
      */
      public static void printArray(int[] arr) {
      for (int n : arr) {
      System.out.print(n + " ");
      }
      System.out.println();
      }
      }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

题解:qoj1875 Nein

题意:给出 \(k,n\),问第 \(n\) 个是 \(10^k-1\) 的倍数的且每个数字不含有 \(9\) 的数是多少。\(k\le 18,n\le 10^{18}\)。 做法: 首先先跳出一个很显然的想法,一开始看这个东西觉得应该是拆成 \(x10^k-x\) 去讨论…

【uni-app】申请高德地图key,封装map.js,实现H5、iOS、Android通过getlocation获取地图定位信息(摘)

一、map组件基础使用<template><view class="contact"><image class="img" :src="formData.headImg"></image><view class="info"><view @…

.NET开发上手Microsoft Agent Framework(一)从开发一个AI美女聊天群组开始

前言 在AI快速发展的今天,微软推出了多个AI开发框架,从早期的AutoGen到Semantic Kernel,再到最新的Microsoft Agent Framework。很多开发者可能会有疑问:为什么微软要推出这么多框架?它们之间有什么区别?本文将通…

10/28

10/28今天在工程实训里学习了金属工艺加工,学习了java的相关网课

大学四年的学费/生活费自足攻略

1997年夏天带着通过亲戚朋友筹集的学费4000元踏上了北上兰州的旅程。我独自一人第一次穿越3000公里来到兰州,办好入学手续住进宿舍。虽然没有政和的老乡,但是有几位南平的老乡来找我,特别是建瓯话和政和话是一样的,…

175天 隧道技术篇防火墙组策略FRPNPSChiselSocks代理端口映射C2上线

三种工具 frp/NPS/Chisel 不用过多的纠结去使用哪一款工具 frp的C2上线 解决的问题: 1.C2上线 2.实现信息收集(两个) 这边可以使用CS生成一个47.xx.xx.xx的后门,然后搭建frp后,进行上线 下面相当于是把端口映射出…

10.28每日总结

今天的主要课程有人机交互技术,软件构造,软件企业文化。完成了上周机器学习的作业以及企业文化的报告,软考准备开始专精刷题里,加油!

102302126李坤铭作业1

作业1 用requests和BeautifulSoup库方法定向爬取给定网址(http://www.shanghairanking.cn/rankings/bcur/2020 )的数据,屏幕打印爬取的大学排名信息。 1)代码: 点击查看代码 import requests from bs4 import Bea…

10月28日日记

1.今天进行工程实训 2.明天学习马哲 3.负载因子为什么通常设置为0.75?

【大模型应用开发】之本地部署大模型

本地部署本地部署一般是在自己的服务器上部署,但这里以本地电脑进行部署为例,由于电脑配置远远无法支持大模型配置要求,届时部署下来的也是阉割版的。本地部署一种方案就是ollama,官方地址:https://ollama.com访问…

link元素的用法及HTML样板

本人学习时候很容易额外扩展,因为很多次见到同一个熟悉但不了解的代码或用法我会很难受,所以我把基本用法都列出来了,看起来会很冗杂(因为不仅不同文章重复,相同文章我也在重复-.-),但结合实例来回对比查阅让我…

Raft 一致性算法简介

引言与背景 分布式系统中,为了在 非拜占庭故障(如节点宕机或网络分区)情况下保持数据一致性,往往需要分布式共识算法来确保多个副本状态统一 。长期以来,Leslie Lamport 提出的 Paxos 算法 一直是这一领域的代表…

10月28号

今天上午进行了铁道认知实训

URL验证绕过速查表:全面解析SSRF与CORS绕过技术

本文详细介绍了PortSwigger最新发布的URL验证绕过速查表工具,涵盖域名混淆、伪相对URL、环回地址编码等核心技术,帮助安全测试人员快速生成绕过payload,有效检测SSRF、CORS配置错误等漏洞。介绍URL验证绕过速查表 U…

https://avoid.overfit.cn/post/44c8d547475340d59aa4480f634ea67f

现在的 Agent 系统有个很明显的问题 —— 会话一结束,什么都忘了。 这不是个技术缺陷,但是却限制了整个系统的能力边界。Agent 可以做推理、规划、执行复杂任务,但就是记不住之前发生过什么。每次对话都像是第一次见…

23题黄金分割

某同学在学习了黄金分割后对于黄金分割产生了浓厚的兴趣,于是他开始探究有关黄金分割的相关性质,请你帮助他完成以下任务。【任务一】作一个黄金分割 (1)如图, \(BC \perp AB\), \(BC = \frac{1}{2} AB\),作 \(…

记录一次成功的springboot2

pom文件<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"x…

算法学习-素数筛法【埃氏筛法、线性筛法】

普通筛法: 核心思路: 使用一个布尔数组记录此数是否为素数, 从2~n便利, 如果是此数记录为素数 向后维护数组,此素数的K倍均为非素数,直到大于n. ^时间复杂度O(nlogn) 便利+维护 埃式筛法 初式: 同线性筛法,依次遍历向后…

日总结 19

C#是基于.NET框架的托管语言,由CLR(公共语言运行时)负责自动内存管理(垃圾回收),开发效率高,更适合快速构建Windows应用、Web服务、Unity游戏等上层应用,编译后生成中间语言(IL),跨平台依赖.NET Core/5+;而…