插入排序專欄

插入排序(Insertion Sort)是一種簡單直觀的排序算法,其思想源于我們日常生活中整理撲克牌的方式。本文將詳細解析插入排序的工作原理,通過 Java 實現代碼進行分析,深入探討其時間復雜度的計算過程,并闡述其適用場景與性能特點。

什么是插入排序?

插入排序的核心思想是:將數組分為已排序區間和未排序區間,初始時已排序區間只有一個元素(數組的第一個元素)。然后,我們依次從無排序區間中取出元素,插入到已排序區間的合適位置,直到整個數組有序。

這種排序方式類似于我們玩撲克牌時,每次拿起一張牌,然后將它插入到手中已有序的牌組中的正確位置。

Java 實現代碼解析

下面是一個基于泛型的插入排序實現,能夠對任何實現了 Comparable 接口的數據類型進行排序:

public class Insertion {public static void main(String[] args) {Integer[] integers = new Integer[10];for (int i = 0; i < integers.length; i++) {integers[i] = (int) (Math.random() * 100);}sort(integers);for (int i = 0; i < integers.length; i++) {System.out.print(integers[i]+" ");}}public static void sort(Comparable[] a){//外層循環將為排序數據依次產出for (int i = 1; i < a.length; i++) {//內存循環將產出的數據與已排序的作比較for (int j = 0; j < i; j++) {//如果產出的數據小于已排序的數據,就交換if(greater(a[j],a[i])){exchange(a,i,j);}}}}//比較v是否大于n;public static boolean greater(Comparable v,Comparable n){//調用comparable的方法//v大于n是返回 1,//v等于n時返回 0,//v小時n時返回 -1int i = v.compareTo(n);return i==1;}//交換方法public static void exchange(Comparable[] a,int i,int j){Comparable temp = a[i];a[i] = a[j];a[j] = temp;}
}

代碼工作原理詳解

讓我們逐步解析插入排序的工作流程:

  1. 初始化:我們從數組的第二個元素開始(索引 1),因為第一個元素本身可以視為一個已排序的區間。

  2. 外層循環for (int i = 1; i < a.length; i++) 負責遍歷未排序區間,依次取出每個待插入的元素。

  3. 內層循環for (int j = 0; j < i; j++) 負責在已排序區間(索引 0 到 i-1)中找到當前元素的合適位置。

  4. 比較與交換:通過greater(a[j], a[i])方法比較元素大小,如果發現當前元素(a [i])小于已排序區間的某個元素(a [j]),則通過exchange(a, i, j)方法交換它們的位置。

  5. 完成排序:當外層循環執行完畢,整個數組就變成了有序數組。

插入排序的時間復雜度深度分析

時間復雜度是衡量算法效率的重要指標,插入排序的時間復雜度分析需要考慮比較操作和交換操作的次數。

最壞情況時間復雜度

最壞情況發生在數組完全逆序的情況下。此時,對于每個待插入的元素,都需要與已排序區間的所有元素進行比較,并且進行交換。

假設數組長度為 n。

  • 當 i=1 時,內層循環 j 從 0 到 0,需要進行 1 次比較,若逆序則進行 1 次交換。

  • 當 i=2 時,內層循環 j 從 0 到 1,需要進行 2 次比較,若逆序則進行 2 次交換。

  • ......

  • 當 i=n-1 時,內層循環 j 從 0 到 n-2,需要進行 n-1 次比較,若逆序則進行 n-1 次交換。

比較操作的總次數為:1+2+3+...+(n-1) = n (n-1)/2,這是一個關于 n 的二次函數,其數量級為 O (n2)。

交換操作在最壞情況下與比較操作的次數相同,同樣為 n (n-1)/2,數量級也為 O (n2)。

所以,插入排序最壞情況的時間復雜度為 O (n2)。

最好情況時間復雜度

最好情況發生在數組已經有序的情況下。此時,對于每個待插入的元素,與已排序區間的第一個元素比較后,就不需要再進行后續的比較和交換操作。

當數組有序時,對于每個 i(從 1 到 n-1),內層循環 j=0 時,比較一次就會發現當前元素不小于已排序區間的元素,內層循環結束,沒有交換操作。

比較操作的總次數為 n-1 次,一比較發現都為最大值,都不需要交換,有n個數據就要比較(n-1)次,是一個線性增長的數量級,即 O (n)。

交換操作的次數為 0,數量級為 O (1)。

所以,插入排序最好情況的時間復雜度為 O (n)。

平均情況時間復雜度

平均情況需要考慮數組的所有可能排列情況,并計算其平均的比較和交換次數。

對于長度為 n 的數組,在平均情況下,每個待插入元素需要與已排序區間中的一半元素進行比較。

比較操作的總次數約為:(1+2+3+...+(n-1))/2 = n (n-1)/4,數量級為 O (n2)。

交換操作的次數在平均情況下與比較操作的次數大致相同,也約為 n (n-1)/4,數量級為 O (n2)。

所以,插入排序平均情況的時間復雜度為 O (n2)。

插入排序的空間復雜度

插入排序是一種原地排序算法,在排序過程中,不需要額外的存儲空間來存儲數組元素,只需要使用常數級別的額外變量(如 i、j、temp 等)來輔助排序操作。

因此,插入排序的空間復雜度為 O (1)。

插入排序的穩定性

穩定性是指排序算法在排序過程中,對于相等元素的相對位置是否保持不變。

在插入排序中,當待插入元素與已排序區間的元素相等時,由于我們的比較條件是 “如果當前元素小于已排序區間的元素,則交換它們”,相等的元素不會發生交換,所以相等元素的相對位置在排序后不會改變。

因此,插入排序是穩定的排序算法。

插入排序的優化思路

上面的實現是最基礎的插入排序版本,我們可以對其進行優化:

  1. 減少交換次數:可以將比較和交換分開,先找到合適位置,再將元素一次性插入,而不是每次比較都交換。

  2. 二分查找優化:在已排序區間查找插入位置時,可以使用二分查找代替線性查找,減少比較次數。

優化后的插入排序代碼通常能提升 20%-30% 的性能。

適用場景

插入排序特別適合以下場景:

  • 數據量較小的情況(通常 n < 100)

  • 數組已經基本有序的情況

  • 對穩定性有要求的場景

  • 作為更復雜排序算法的子過程(如歸并排序處理小規模子數組時)

在 Java 的 Arrays.sort () 方法中,當處理小數組時就使用了插入排序。

總結

插入排序雖然時間復雜度為 O (n2),但它實現簡單、空間效率高,并且在處理小規模或基本有序的數據時表現良好。通過對其時間復雜度的深入分析,我們能更清晰地了解在不同場景下插入排序的性能表現。理解插入排序的原理和時間復雜度計算,有助于我們更好地掌握更復雜的排序算法,也能在合適的場景中靈活應用它。

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

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

相關文章

高效Unicode字符表示:一種創新的詞表構建策略分析

在自然語言處理中&#xff0c;處理多語言和特殊字符的表示始終是一項挑戰。本文將分析一種創新的詞表構建策略&#xff0c;該策略通過數學優化和雙token機制&#xff0c;在保持詞表緊湊的同時實現了對Unicode字符的全面覆蓋。 詞表構建的核心邏輯 該策略包含四個關鍵步驟&#…

python與物聯網基礎知識

軟件準備&#xff1a;軟件&#xff1a;thonny-4.0.1-windows-portable(win10,11系統64位)驅動&#xff1a;CP210x_Windows_Drivers固件&#xff1a;esp8266-1m-20220618-v1.19.1.bin物料準備&#xff1a;面包板、開發板、電源線一、安裝與調試&#xff1a;1.在軟件文件中找到th…

SVN提交服務器拒絕訪問的問題

SVN提交服務器拒絕訪問的問題 介紹 分析 1.服務器的SVN沒有開啟 2.服務器的網絡端口除了問題沒有開放端口 3.客戶端的SVN配置除了問題刷新一下數據 4.客戶端的SVN重裝 找原因 1.初步以為是**防火墻**的問題 2.網絡運營商的問題 總結 介紹 SVN相信大家都用過,今天反饋一個比較…

【Linux】庫制作與原理

前言 本篇博客我們來認識下庫方面的知識 &#x1f493; 個人主頁&#xff1a;zkf ? 文章專欄&#xff1a;Linux 若有問題 評論區見&#x1f4dd; &#x1f389;歡迎大家點贊&#x1f44d;收藏?文章 目錄 1.什么是庫 2.靜態庫 2.1靜態庫的生成 2.2靜態庫的使用 3.動態庫 …

Android ADB 常用指令全解析

ADB&#xff08;Android Debug Bridge&#xff09;是 Android 開發和測試不可或缺的調試工具&#xff0c;它建立了電腦與 Android 設備之間的通信橋梁&#xff0c;通過命令行指令可實現對設備的全方位控制。掌握 ADB 指令能大幅提升開發效率&#xff0c;解決各類調試難題。本文…

使用 Rust 創建 32 位 DLL 的完整指南

使用 Rust 創建 32 位 DLL 的完整指南 在 Rust 中創建 32 位 DLL 需要特定的工具鏈配置和編譯選項。以下是詳細步驟和最佳實踐&#xff1a; 環境準備 1. 安裝 Rust 工具鏈 # 安裝 Rust curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh# 安裝 32 位目標 rustu…

算法基礎 第3章 數據結構

1.單調棧 1.什么是單調棧 單調棧&#xff0c;即具有單調性的棧。 實現 #include <iostream> #include <stack> using namespace std; const int N 3e6 10; int a[N], n; void test1() {stack<int> st; // 維護?個單調遞增的棧for(int i 1; i < n; i…

[機器學習]08-基于邏輯回歸模型的鳶尾花數據集分類

使用sklearn的LogisticRegression多分類模型程序代碼&#xff1a;import numpy as np from sklearn.linear_model import LogisticRegression import matplotlib.pyplot as plt import matplotlib as mpl from sklearn import datasets from sklearn import preprocessing impo…

【STM32入門教程】stm32簡介

一、STM32簡介二、ARM三、stm32f103c8t6四、命名規則五、系統結構六、引腳定義七、啟動配置一般情況下&#xff0c;都是在flash開始程序&#xff0c;而啟動程序也可以進行配置在其他地方啟動程序&#xff0c;通過配置boot0和boot1來進行配置八、最小系統電路

SAE J2716多協議網關的硬件架構與實時協議轉換機制解析

本文解析符合SAE J2716標準的工業級協議轉換設備技術架構&#xff0c;通過拆解其四路雙向SENT通道與多總線&#xff08;CANFD/Ethernet/USB&#xff09;的實時交互機制、MicroSD獨立日志系統設計及模擬量動態映射方案&#xff0c;為汽車電子與工業通信開發者提供可復用的技術參…

VS2022+QT5.15.2+OCCT7.9.1的開發環境搭建流程

以下是VS2022 QT5.15.2 OCCT7.9.1開發環境搭建的完整流程&#xff1a; 一、安裝Visual Studio 2022 下載安裝程序 訪問VS官網下載Community版安裝組件 選擇"使用C的桌面開發"工作負載勾選&#xff1a; MSVC v143 - VS 2022 C x64/x86生成工具Windows 10 SDK (建議…

數據庫訪問模式詳解

數據庫訪問模式詳解數據庫訪問模式是軟件架構中數據訪問層&#xff08;Data Access Layer&#xff09;設計的核心&#xff0c;它定義了應用程序如何與數據庫進行交互的策略和方法。選擇合適的訪問模式對于系統的性能、可維護性、可擴展性、事務一致性和開發效率至關重要。不同的…

BGE向量算法

一、是什么 什么是BGE向量算法&#xff1f;先說說網上的概念吧。本文不講解太深的算法知識&#xff0c;主要講解如何用&#xff01; BGE&#xff08;BAAI General Embedding&#xff09;是北京智源研究院開源的“通用語義向量模型”。一句話&#xff1a;把中文或英文句子變成…

AI數據倉庫的核心優勢解析

內容概要本文旨在全面解析AI數據倉庫的核心優勢&#xff0c;為讀者提供清晰的框架。文章首先從基礎定義出發&#xff0c;探討其如何高效整合多源數據&#xff0c;并支持人工智能與機器學習應用。隨后&#xff0c;將詳細闡述處理TB級數據的能力&#xff0c;包括兼容結構化和非結…

具身智能Scaling Law缺失:機器人界的“摩爾定律“何時誕生?

8月9日&#xff0c;在世界機器人大會的演講臺上&#xff0c;宇樹科技創始人王興興談論到目前機器人運動控制領域存在的RL Scaling Law問題&#xff0c;他認為現在的機器人在學習一項新的技能時&#xff0c;往往都是需要從頭開始研究以及教學。而在未來更加希望的是能夠在原有的…

【跨越 6G 安全、防御與智能協作:從APT檢測到多模態通信再到AI代理語言革命】

跨越 6G 安全、防御與智能協作&#xff1a;從APT檢測到多模態通信再到AI代理語言革命引言單篇總結**2. Integrated Multimodal Sensing and Communication: Challenges, Technologies, and Architectures****3. Why do AI agents communicate in human language?**引言 在邁向…

微前端-解決MicroApp微前端內存泄露問題

前言 之前使用京東微前端框架MicroApp集成10個微前端的頁面到AngularJs的后臺管理系統中&#xff0c;每個微前端做成一個菜單&#xff0c;一共10個&#xff0c;每次打開都是一個新的微前端&#xff0c;但是發現打開的微前端越多&#xff0c;容易造成內存泄露&#xff0c;下面講…

線性代數 · 向量運算 | 叉乘 / 幾何意義 / 推導

注&#xff1a;本文為 “線性代數 向量運算” 相關合輯。 圖片清晰度受引文原圖所限。 略作重排&#xff0c;未整理去重。 如有內容異常&#xff0c;請看原文。 數學基礎 —— 向量運算&#xff08;叉乘&#xff09; keng_s 于 2016-08-05 17:17:57 發布 1_ 向量的叉乘 向量…

方法中只包含查詢操作需要添加事務嗎?

方法中只包含查詢操作需要添加事務嗎?絕大部分情況都不需要 是否需要為包含數據庫查詢操作的方法添加 @Transactional 注解,取決于業務需求和查詢操作的特性,不能一概而論。以下是具體分析: 一、不需要添加 @Transactional 的常見場景 如果查詢操作滿足以下條件,通常不需…

MTK平臺Wi-Fi學習--wifi channel 通過國家碼進行功率限制和wifi eFEM 基本配置和wifi Tx SEM問題

一. 國家碼可以用來限制功率上限,可以針對各國家實現By channel降功率的能力 可以通過country code來設置不同channel的power limit,操作方法如下: 在rlm_txpwr_init.h文件中g_rRlmPowerLimitConfiguration[]下添加需要限制功率的channel, 例如:國家碼CN,信道:CH1,po…