Java常見排序算法實現

以下是Java中幾種常見排序算法的實現,包括冒泡排序、選擇排序、插入排序、快速排序和歸并排序。

各排序算法特點說明:

  1. 冒泡排序

    • 原理:重復比較相鄰元素,將大的元素逐步"冒泡"到數組末尾
    • 特點:穩定排序,適合小規模數據,可優化(加入交換標記提前退出)
    • 空間復雜度:O(1)(原地排序)
  2. 選擇排序

    • 原理:每次從剩余元素中找到最小元素,放到已排序區間末尾
    • 特點:不穩定(可能改變相等元素的相對順序),交換次數少
    • 空間復雜度:O(1)(原地排序)
  3. 插入排序

    • 原理:將元素逐個插入到前面已排序的區間中合適的位置
    • 特點:穩定排序,對近乎有序的數據效率很高(接近O(n))
    • 空間復雜度:O(1)(原地排序)
  4. 快速排序

    • 原理:通過分區操作將數組分為兩部分,遞歸排序子數組
    • 特點:實際應用中最快的排序算法之一,不穩定,最壞情況性能差
    • 空間復雜度:O(log n)(遞歸棧空間)
  5. 歸并排序

    • 原理:將數組分成兩半分別排序,再合并兩個有序子數組
    • 特點:穩定排序,性能穩定(始終O(n log n)),需要額外空間
    • 空間復雜度:O(n)(需要臨時數組)
import java.util.Arrays;public class SortingAlgorithms {// 1. 冒泡排序(穩定,O(n2))public static void bubbleSort(int[] arr) {if (arr == null || arr.length <= 1) return;int n = arr.length;// 外層循環控制需要進行多少輪比較for (int i = 0; i < n - 1; i++) {boolean swapped = false;// 內層循環每輪將最大元素"冒泡"到末尾for (int j = 0; j < n - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交換元素int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;swapped = true;}}// 如果本輪沒有交換,說明數組已有序,提前退出if (!swapped) break;}}// 2. 選擇排序(不穩定,O(n2))public static void selectionSort(int[] arr) {if (arr == null || arr.length <= 1) return;int n = arr.length;// 外層循環控制未排序區間的起點for (int i = 0; i < n - 1; i++) {// 找到未排序區間中最小元素的索引int minIndex = i;for (int j = i + 1; j < n; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 將最小元素與未排序區間的第一個元素交換int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}// 3. 插入排序(穩定,O(n2),適合近乎有序的數據)public static void insertionSort(int[] arr) {if (arr == null || arr.length <= 1) return;int n = arr.length;// 從第二個元素開始,將其插入到前面的有序區間for (int i = 1; i < n; i++) {int key = arr[i]; // 當前要插入的元素int j = i - 1;// 移動有序區間中大于key的元素while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}// 將key插入到正確位置arr[j + 1] = key;}}// 4. 快速排序(不穩定,平均O(n log n),最壞O(n2))public static void quickSort(int[] arr) {if (arr == null || arr.length <= 1) return;quickSort(arr, 0, arr.length - 1);}private static void quickSort(int[] arr, int left, int right) {if (left < right) {// 分區操作,返回基準元素的正確位置int pivotIndex = partition(arr, left, right);// 遞歸排序基準元素左右兩側的子數組quickSort(arr, left, pivotIndex - 1);quickSort(arr, pivotIndex + 1, right);}}private static int partition(int[] arr, int left, int right) {int pivot = arr[right]; // 以最右側元素作為基準int i = left - 1; // i指向小于基準的元素的最后位置// 遍歷數組,將小于基準的元素放到左側for (int j = left; j < right; j++) {if (arr[j] <= pivot) {i++;// 交換元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 將基準元素放到正確位置int temp = arr[i + 1];arr[i + 1] = arr[right];arr[right] = temp;return i + 1; // 返回基準元素的索引}// 5. 歸并排序(穩定,O(n log n),需要額外空間)public static void mergeSort(int[] arr) {if (arr == null || arr.length <= 1) return;mergeSort(arr, 0, arr.length - 1, new int[arr.length]);}private static void mergeSort(int[] arr, int left, int right, int[] temp) {if (left < right) {int mid = left + (right - left) / 2; // 避免溢出// 遞歸排序左右兩半mergeSort(arr, left, mid, temp);mergeSort(arr, mid + 1, right, temp);// 合并兩個有序子數組merge(arr, left, mid, right, temp);}}private static void merge(int[] arr, int left, int mid, int right, int[] temp) {int i = left; // 左子數組的起始索引int j = mid + 1; // 右子數組的起始索引int k = left; // 臨時數組的起始索引// 合并兩個子數組到臨時數組while (i <= mid && j <= right) {if (arr[i] <= arr[j]) {temp[k++] = arr[i++];} else {temp[k++] = arr[j++];}}// 復制左子數組剩余元素while (i <= mid) {temp[k++] = arr[i++];}// 復制右子數組剩余元素while (j <= right) {temp[k++] = arr[j++];}// 將臨時數組中的元素復制回原數組for (k = left; k <= right; k++) {arr[k] = temp[k];}}// 測試public static void main(String[] args) {int[] arr = {64, 34, 25, 12, 22, 11, 90};int[] copy;copy = Arrays.copyOf(arr, arr.length);bubbleSort(copy);System.out.println("冒泡排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);selectionSort(copy);System.out.println("選擇排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);insertionSort(copy);System.out.println("插入排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);quickSort(copy);System.out.println("快速排序: " + Arrays.toString(copy));copy = Arrays.copyOf(arr, arr.length);mergeSort(copy);System.out.println("歸并排序: " + Arrays.toString(copy));}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/98177.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/98177.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/98177.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Python爬蟲實戰:研究Pandas,構建地理信息數據采集和分析系統

1. 引言 1.1 研究背景 地理數據作為描述地球表面空間要素的數據,包含了豐富的空間位置、分布特征和屬性信息,在城市規劃、環境監測、商業分析等眾多領域發揮著不可替代的作用。隨著 "數字地球"、"智慧城市" 等概念的提出和發展,地理數據的重要性日益凸…

nvm安裝node后出現報錯: “npm 不是內部或外部命令,也不是可運行的程序 或批處理文件”

一、問題描述 使用nvm安裝node后&#xff0c;使用npm命令報錯如下 報錯1&#xff1a;npm : 無法將“npm”項識別為 cmdlet、函數、腳本文件或可運行程序的名稱。請檢查名稱的拼寫&#xff0c;如果包括路徑&#xff0c;請確保路徑正確&#xff0c;然后再試一次。報錯2&#xf…

【高等數學】第十二章 無窮級數——第二節 常數項級數的審斂法

上一節&#xff1a;【高等數學】第十二章 無窮級數——第一節 常數項級數的概念和性質 總目錄&#xff1a;【高等數學】 目錄 文章目錄1. 正項級數及其審斂法1. 正項級數及其審斂法 正項級數 各項都是正數或零的級數稱為正項級數正項級數收斂 正項級數 ∑n1∞un\displaystyle\…

圖觀 流渲染場景編輯器

一、 產品簡介圖觀 流渲染場景編輯器&#xff0c;以編輯器插件形式&#xff0c;在Unreal Engine中輕松編輯并發布數字孿生場景。支持 GIS 全球/局部 數字孿生場景構建&#xff0c;并預置 圖觀技術架構工程模板&#xff0c;支持對 場景效果、鏡頭視野&#xff0c;環境時間氣象、…

Visual Studio 函數頭顯示引用個數

在visual studio 里面有自帶的顯示引用方案 codeLens

數據結構的哈希表沖突解決方法

哈希表是一種高效的數據結構,通過哈希函數將鍵映射到存儲位置。但由于哈希函數可能將不同鍵映射到相同位置(稱為哈希沖突),需要有效的方法來解決沖突。以下是常見的沖突解決策略,每種方法都有其原理、優缺點和適用場景。我將逐步解釋這些方法,確保內容清晰可靠。 1. 開放…

MySQL 基礎概念與簡單使用

MySQL 基礎概念與簡單使用 一、數據庫基本概念 1、數據庫定義 數據庫&#xff08;Database&#xff09;是存儲在計算機內、有組織、可共享的數據集合&#xff0c;用于高效地管理大量數據。 2、數據庫分類 按數據模型分類&#xff1a; 關系型數據庫&#xff08;如 MySQL、Oracle…

關系模型的數據結構

在關系數據庫這個世界里&#xff0c;所有東西&#xff08;包括你要記錄的人、物、事&#xff0c;以及它們之間的聯系&#xff09;都用一種叫做“關系”的結構來表示。而這種“關系”的靈魂&#xff0c;就是“碼”&#xff08;Key&#xff09;。1. 核心思想&#xff1a;萬物皆“…

180 課時吃透 Go 語言游戲后端系列0:序言

零基礎能學習 Go 游戲后端開發嗎&#xff1f; 當然能學啦&#xff01;別擔心&#xff0c;就算你之前對編程一竅不通&#xff0c;也完全沒問題。我特意準備了180課時的開發課程&#xff0c;由淺入深、從理論到實踐帶領大家學會使用GO語言進行游戲后端開發。 編程就像學一門新語…

Android-SerialPort-API-master源碼 串口調試 權限分析 定制

我把界面美化了一下Android-SerialPort-API-master源碼 1.加了發送按鈕 2.加上固定/dev/ttyGS1和GS9串口權限問題已經查清楚了。app與PosServer都是使用google的SerialPort方案。我做的app 都多使用一個函數available()&#xff0c;這個函數是非常有用的。在上位機發送單條指令…

KVM 入門使用手冊

KVM 入門使用手冊 1. 概述 2. 安裝 在 Ubuntu/Debian 上安裝 在 RHEL/CentOS/Fedora 上安裝 3. 網絡配置 查看默認網絡 使用橋接網絡 (推薦用于服務器) 4. 創建虛擬機 方法一:使用圖形界面 (virt-manager) 方法二:使用命令行 (virt-install) 5. 管理虛擬機 使用 `virsh` 命令…

Devise Ruby身份驗證解決方案全攻略

文章目錄 前言Devise到底是什么&#xff1f;為什么選擇Devise&#xff1f;環境準備Devise安裝指南第一步&#xff1a;添加Devise到你的Gemfile第二步&#xff1a;初始化Devise第三步&#xff1a;生成用戶模型第四步&#xff1a;運行數據庫遷移 Devise核心模塊詳解Database Auth…

68-python操作SQLite

1. 了解SQLite SQLite&#xff0c;是一款輕型的數據庫&#xff0c;是遵守ACID的關系型數據庫管理系統&#xff0c;它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。它的設計目標是嵌入式的&#xff0c;而且已經在很多嵌入式產品中使用了它&#xff0c;它占用…

在Qt項目中使用QtConcurrent::run,實現異步等待和同步調用

在使用Qt進行開發時&#xff0c;經常需要使用異步方法&#xff0c;不同于C#的async/await&#xff0c;Qt中提供了QtConcurrent::run接口方法可供調用&#xff0c;習慣了C#的await&#xff0c;便想著能不能封裝幾個類似的函數在項目中使用&#xff0c;探索了下&#xff0c;有如下…

視頻分類 pytorchvideo

目錄 1. 速度 vs 精度分析 mvit: r2plus1d_r50 推理代碼&#xff1a; x3d_xs推理代碼&#xff1a; R(21)D X3D&#xff08;輕量級&#xff0c;速度快&#xff09; I3D&#xff08;經典 3D CNN&#xff09; 替換分類層&#xff08;適配你的任務&#xff09; https://gith…

OpenTiny NEXT 內核新生:生成式UI × MCP,重塑前端交互新范式!

近期&#xff0c;我們推出 OpenTiny NEXT —— OpenTiny的下一代企業級前端智能開發解決方案。這不僅是一次技術升級&#xff0c;更是一場用戶交互范式的變革&#xff1a;從傳統的人機交互升級成為人機交互范式和智能體交互范式的融合。我們堅信&#xff0c;每一個企業應用都值…

深度神經網絡1——梯度問題+標簽數不夠問題

要解決一個復雜問題&#xff0c;可能要訓練更深的神經網絡&#xff0c;可能會10層及以上&#xff0c;每層包含數百個神經元&#xff0c;成千上萬個連接。這樣大的神經網絡在訓練的時候可能會遇到以下問題&#xff1a;這樣在進行反向傳播的時候&#xff0c;隨著層數越來越低會遇…

(筆記)內存文件映射mmap

內存文件映射是一種將文件內容映射到進程的虛擬地址空間的技術&#xff0c;使得文件可以被視為內存的一部分&#xff0c;從而允許程序直接對這部分內存進行讀寫操作&#xff0c;而無需傳統的文件 I/O 調用。這種方法不僅簡化了文件操作&#xff0c;還提高了處理效率。 在Linux…

Golang中的NaN(Not a Number)

Golang中的NaN&#xff08;Not a Number&#xff09; 在Go語言中&#xff0c;NaN是浮點數&#xff08;特別是float32和float64&#xff09;中的一個特殊值&#xff0c;表示未定義或不可表示的數值。 go中&#xff0c;除數為0時并不會返回error或者nil&#xff0c;而是返回無窮大…

微軟圖引擎GraphEngine深度解析:分布式內存計算的技術革命

? "在大數據的汪洋中&#xff0c;圖引擎就像是一艘能夠高速穿越復雜關系網絡的超級快船" 引言&#xff1a;當內存遇上圖計算的火花 在這個數據爆炸的時代&#xff0c;傳統的關系型數據庫已經難以應對復雜關系數據的查詢挑戰。當Facebook的社交網絡擁有數十億用戶關…