【算法基礎】選擇排序算法 - JAVA

一、算法基礎

1.1 什么是選擇排序

選擇排序是一種簡單直觀的排序算法,它的工作原理是:首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再從剩余未排序元素中繼續尋找最小(或最大)元素,然后放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。

1.2 選擇排序的基本思想

選擇排序的核心思想是:

  • 將輸入數據分為已排序區域和未排序區域
  • 不斷從未排序區域選擇最小元素,放入已排序區域的末尾
  • 重復上述過程直到全部排序完成

1.3 時間復雜度

選擇排序的時間復雜度分析如下:

  • 最好情況時間復雜度:O(n2)
  • 最壞情況時間復雜度:O(n2)
  • 平均時間復雜度:O(n2)

無論輸入數據是否已經部分排序,選擇排序始終需要進行 n(n-1)/2 次比較,因此其時間復雜度總是 O(n2)。

1.4 空間復雜度

選擇排序是一種原地排序算法,它只需要一個用于交換的臨時變量,因此空間復雜度為 O(1)

二、Java實現

2.1 基礎實現

public class SelectionSort {public static void selectionSort(int[] arr) {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;}}// 將找到的最小值與未排序區域的第一個元素交換if (minIndex != i) {int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}}// 測試代碼public static void main(String[] args) {int[] arr = {64, 25, 12, 22, 11};selectionSort(arr);System.out.println("排序后的數組:");for (int i : arr) {System.out.print(i + " ");}}
}

2.2 算法步驟解析

  1. 初始狀態:整個數組視為未排序區域
  2. 第一次迭代
    • 在整個數組中找到最小元素
    • 將其與數組第一個元素交換位置
    • 數組第一個元素現在位于正確位置
  3. 第二次迭代
    • 從第二個元素開始,在剩余未排序元素中找到最小值
    • 將其與數組第二個元素交換位置
  4. 重復過程:繼續執行,直到所有元素都排序完畢

三、選擇排序的特點

3.1 優點

  • 實現簡單,易于理解和編碼
  • 交換次數少:每次內循環只需要進行一次交換操作,最多進行 n-1 次交換
  • 原地排序:不需要額外的存儲空間
  • 穩定性可控:可以實現為穩定排序算法(通過特定實現方式)

3.2 缺點

  • 時間效率低:無論輸入如何,時間復雜度始終為 O(n2)
  • 不適合大規模數據:當數據量大時,性能顯著下降
  • 不會提前終止:即使數組已經排序,算法仍會執行完所有步驟

四、算法優化方案

4.1 雙向選擇排序

雙向選擇排序在每次迭代中同時查找最小值和最大值,減少了循環次數:

public static void bidirectionalSelectionSort(int[] arr) {int left = 0;int right = arr.length - 1;while (left < right) {int minIndex = left;int maxIndex = left;// 找出最小值和最大值for (int i = left + 1; i <= right; i++) {if (arr[i] < arr[minIndex]) {minIndex = i;}if (arr[i] > arr[maxIndex]) {maxIndex = i;}}// 將最小值放到左邊if (minIndex != left) {int temp = arr[left];arr[left] = arr[minIndex];arr[minIndex] = temp;// 如果最大值是left,那么交換后最大值位置變為minIndexif (maxIndex == left) {maxIndex = minIndex;}}// 將最大值放到右邊if (maxIndex != right) {int temp = arr[right];arr[right] = arr[maxIndex];arr[maxIndex] = temp;}left++;right--;}
}

4.2 使用堆數據結構

可以使用最小堆來優化選擇排序:

  1. 構建一個最小堆 O(n)
  2. 依次取出堆頂元素 O(log n)

這種方法實際上就是堆排序,時間復雜度降低到 O(n log n)。

五、實例分析

5.1 示例數組排序過程

以數組 [64, 25, 12, 22, 11] 為例:

  1. 第一次迭代
    • 找到最小值 11(索引 4)
    • 交換11和64:[11, 25, 12, 22, 64]
    • 已排序:[11],未排序:[25, 12, 22, 64]
  2. 第二次迭代
    • 在剩余部分找到最小值 12(索引 2)
    • 交換12和25:[11, 12, 25, 22, 64]
    • 已排序:[11, 12],未排序:[25, 22, 64]
  3. 第三次迭代
    • 在剩余部分找到最小值 22(索引 3)
    • 交換22和25:[11, 12, 22, 25, 64]
    • 已排序:[11, 12, 22],未排序:[25, 64]
  4. 第四次迭代
    • 在剩余部分找到最小值 25(索引 3)
    • 不需要交換(已在正確位置)
    • 已排序:[11, 12, 22, 25],未排序:[64]
  5. 排序完成[11, 12, 22, 25, 64]

5.2 性能分析

對比不同輸入規模的性能表現

  • 小規模數據(n ≤ 50):選擇排序性能可接受
  • 中等規模數據(50 < n ≤ 1000):性能明顯下降
  • 大規模數據(n > 1000):性能嚴重下降,不推薦使用

六、應用場景

6.1 適用場景

  • 小規模數據排序:當數據量較小時,選擇排序簡單易實現
  • 對交換操作敏感的場景:選擇排序的交換次數最多為 n-1 次
  • 輔助教學:作為排序算法的基礎教學示例
  • 內存受限的嵌入式系統:實現簡單且空間復雜度低

6.2 不適用場景

  • 大規模數據排序:性能太低,應選擇更高效的算法
  • 幾乎已排序的數據:選擇排序無法利用數據的部分有序性

七、總結

選擇排序是一種簡單直觀的排序算法,核心思想是不斷從未排序區域中選擇最小元素放入已排序區域

核心要點

  • 時間復雜度始終為 O(n2),無論輸入如何
  • 空間復雜度為 O(1),是一種原地排序算法
  • 交換次數較少,最多進行 n-1 次交換
  • 實現簡單,代碼易于理解和編寫
  • 對于大型數據集不推薦使用

選擇排序雖然不是最高效的排序算法,但它的簡單性和低空間復雜度使其在特定場景下仍有價值。對于編程初學者來說,理解選擇排序有助于掌握排序算法的基本概念及其實現方法。

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

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

相關文章

LabVIEW異步調用VI介紹

在 LabVIEW 編程環境里&#xff0c;借助結合異步 VI 調用&#xff0c;并使用 “Open VI Reference” 函數上的 “Enable simultaneous calls on reentrant VIs” 選項&#xff08;0x40&#xff09;&#xff0c;達成了對多個 VI 調用執行效率的優化。以下將從多方面詳細介紹該 V…

Leetcode刷題 | Day50_圖論02_島嶼問題01_dfs兩種方法+bfs一種方法

一、學習任務 99. 島嶼數量_深搜dfs代碼隨想錄99. 島嶼數量_廣搜bfs100. 島嶼的最大面積101. 孤島的總面積 第一類DFS&#xff08;主函數中處理第一個節點&#xff0c;DFS處理相連節點&#xff09;&#xff1a; 主函數中先將起始節點標記為已訪問DFS函數中不處理起始節點&…

深入理解網絡安全中的加密技術

1 引言 在當今數字化的世界中&#xff0c;網絡安全已經成為個人隱私保護、企業數據安全乃至國家安全的重要組成部分。隨著網絡攻擊的復雜性和頻率不斷增加&#xff0c;保護敏感信息不被未授權訪問變得尤為關鍵。加密技術作為保障信息安全的核心手段&#xff0c;通過將信息轉換為…

舊版本NotionNext圖片失效最小改動解決思路

舊版本NotionNext圖片失效最小改動解決思路 契機 好久沒寫博客了&#xff0c;最近在notion寫博客的時候發現用notionNext同步到個人網站時&#xff0c;圖片無法預覽。猜測是notion加了防盜鏈措施&#xff0c;去notionNext官方github上尋找解決方案&#xff0c;需要升級到4.8.…

深度學習筆記40_中文文本分類-Pytorch實現

&#x1f368; 本文為&#x1f517;365天深度學習訓練營 中的學習記錄博客&#x1f356; 原作者&#xff1a;K同學啊 | 接輔導、項目定制 一、我的環境 1.語言環境&#xff1a;Python 3.8 2.編譯器&#xff1a;Pycharm 3.深度學習環境&#xff1a; torch1.12.1cu113torchvision…

010302-oss_反向代理_負載均衡-web擴展2-基礎入門-網絡安全

文章目錄 1 OSS1.1 什么是 OSS 存儲&#xff1f;1.2 OSS 核心功能1.3 OSS 的優勢1.4 典型使用場景1.5 如何接入 OSS&#xff1f;1.6 注意事項1.7 cloudreve實戰演示1.7.1 配置cloudreve連接阿里云oss1.7.2 常見錯誤1.7.3 安全測試影響 2 反向代理2.1 正向代理和反向代理2.2 演示…

【 Node.js】 Node.js安裝

下載 下載 | Node.js 中文網https://nodejs.cn/download/ 安裝 雙擊安裝包 點擊Next 勾選使用許可協議&#xff0c;點擊Next 選擇安裝位置 點擊Next 點擊Next 點擊Install 點擊Finish 完成安裝 添加環境變量 編輯【系統變量】下的變量【Path】添加Node.js的安裝路徑--如果…

Python基本語法(自定義函數)

自定義函數 Python語言沒有子程序&#xff0c;只有自定義函數&#xff0c;目的是方便我們重復使用相同的一 段程序。將常用的代碼塊定義為一個函數&#xff0c;以后想實現相同的操作時&#xff0c;只要調用函數名就可以了&#xff0c;而不需要重復輸入所有的語句。 函數的定義…

OpenGL-ES 學習(11) ---- EGL

目錄 EGL 介紹EGL 類型和初始化EGL初始化方法獲取 eglDisplay初始化 EGL選擇 Config構造 Surface構造 Context開始繪制 EGL Demo EGL 介紹 OpenGL-ES 是一個操作GPU的圖像API標準&#xff0c;它通過驅動向 GPU 發送相關圖形指令&#xff0c;控制圖形渲染管線狀態機的運行狀態&…

極簡5G專網解決方案

極簡5G專網解決方案 利用便攜式即插即用私有 5G 網絡提升您的智能創新。為您的企業提供無縫、安全且可擴展的 5G 解決方案。 提供極簡5G專網解決方案 Mantiswave Network Private Limited 提供全面的 5G 專用網絡解決方案&#xff0c;以滿足您企業的獨特需求。我們創新的“…

html:table表格

表格代碼示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!-- 標準表格。 --><table border"5"cellspacing&qu…

tkinter 電子時鐘 實現時間日期 可實現透明

以下是一個使用Tkinter模塊創建一個簡單的電子時鐘并顯示時間和日期的示例代碼&#xff1a; import tkinter as tk import time# 創建主窗口 root tk.Tk() root.overrideredirect(True) # 隱藏標題欄 root.attributes(-alpha, 0.7) # 設置透明度# 顯示時間的標簽 time_labe…

【報錯問題】 macOS 的安全策略(Gatekeeper)阻止了未簽名的原生模塊(bcrypt_lib.node)加載

這個錯誤是由于 macOS 的安全策略&#xff08;Gatekeeper&#xff09;阻止了未簽名的原生模塊&#xff08;bcrypt_lib.node&#xff09;加載 導致的。以下是具體解決方案&#xff1a; 1. 臨時允許加載未簽名模塊&#xff08;推薦先嘗試&#xff09; 在終端運行以下命令&#x…

AI實現制作logo的網站添加可選顏色模板

1.效果圖 LogoPalette.jsx import React, {useState} from react import HeadingDescription from ./HeadingDescription import Lookup from /app/_data/Lookup import Colors from /app/_data/Colors function LogoPalette({onHandleInputChange}) { const [selectOptio…

云原生后端架構的挑戰與應對策略

??個人主頁??:慌ZHANG-CSDN博客 ????期待您的關注 ???? 隨著云計算、容器化以及微服務等技術的快速發展,云原生架構已經成為現代軟件開發和運維的主流趨勢。企業通過構建云原生后端系統,能夠實現靈活的資源管理、快速的應用迭代和高效的系統擴展。然而,盡管云原…

【C++】模板為什么要extern?

模板為什么要extern&#xff1f; 在 C 中&#xff0c;多個編譯單元使用同一個模板時&#xff0c;是否可以不使用 extern 取決于模板的實例化方式&#xff08;隱式或顯式&#xff09;&#xff0c;以及你對編譯時間和二進制體積的容忍度。 1. 隱式實例化&#xff1a;可以不用 ex…

中小企業MES系統數據庫設計

版本&#xff1a;V1.0 日期&#xff1a;2025年5月2日 一、數據庫架構概覽 1.1 數據庫選型 數據類型數據庫類型技術選型用途時序數據&#xff08;傳感器讀數&#xff09;時序數據庫TimescaleDB存儲設備實時監控數據結構化業務數據關系型數據庫PostgreSQL工單、質量、設備等核心…

VUE篇之樹形特殊篇

根節點是level:1, level3及其子節點有關聯&#xff0c;但是和level2和他下面的子節點沒有關聯 思路&#xff1a;采用守護風琴效果&#xff0c;遍歷出level1和level2級節點&#xff0c;后面level3的節點&#xff0c;采用樹形結構進行關聯 <template><div :class"…

洛圣電玩系列部署實錄:一次自己從頭跑通的搭建過程

寫這篇文章不是為了“教大家怎么一步步安裝”&#xff0c;而是想把我自己完整跑通洛圣電玩整個平臺的經歷復盤下來。因為哪怕你找到了所謂的全套源碼資源&#xff0c;如果沒人告訴你這些資源之間是怎么連起來的&#xff0c;你依舊是一臉懵逼。 我拿到的是什么版本&#xff1f; …

騰訊云web服務器配置步驟是什么?web服務器有什么用途?

騰訊云web服務器配置步驟是什么?web服務器有什么用途&#xff1f; Web服務器配置步驟&#xff08;以常見環境為例&#xff09; 1. 安裝Web服務器軟件 Linux系統&#xff08;如Ubuntu&#xff09; Apache: sudo apt update sudo apt install apache2 Nginx: sudo apt install…