【數據結構與算法】十大經典排序算法-希爾排序

🌟個人博客:www.hellocode.top
🏰Java知識導航:Java-Navigate
🔥CSDN:HelloCode.
🌞知乎:HelloCode
🌴掘金:HelloCode
?如有問題,歡迎指正,一起學習~~


希爾排序是一種插入排序的改進版本,旨在解決插入排序在處理大規模數據時的效率問題。通過將數組分為多個子序列并對這些子序列進行局部排序,希爾排序逐步將元素“分組”并逐漸接近它們的最終排序位置。這種逐步的排序方式可以有效減少逆序對的數量,從而加快整體排序過程。

基本思想

希爾排序

這里使用五分鐘學算法大佬的動圖,很清晰

  1. 希爾排序將數組分成若干個子序列,每個子序列包含間隔為 h 的元素,稱為 h-子序列。
  2. 對每個 h-子序列應用插入排序,以實現局部排序。
  3. 不斷縮小 h 的值,重復步驟 2,直到 h 為 1。此時,整個序列基本有序,只需對相鄰元素進行插入排序即可。

一般間隔也就是gap的選取就是數組長度的一半,如上圖所示,原始數組為[8,9,1,7,2,3,5,4,6,0],初始間隔就是5,也就是會將圖中數組分為[8,3][9,5][1,4][7,6][2,0]共5組,然后對這些組合進行插入排序,并不斷縮小gap(每次縮小一半),重復進行插入排序操作,最終就能夠得到有序數組~

對分組不太理解的可以看下圖,非常清晰:

img

代碼實現

代碼的話還是循環,只需要在插入排序外層再加一層循環控制gap 的縮小即可,就是改良版的插入排序(需要對比圖片和插入排序的思路仔細體會),具體代碼如下:

/*** @author HelloCode* @blog https://www.hellocode.top* @date 2023年08月10日 20:59*/
public class ShellSort {public static void main(String[] args) {int[] arr = {8,9,1,7,2,3,5,4,6,0};System.out.println("原數組:" + Arrays.toString(arr));shellSort(arr);System.out.println("排序后:" + Arrays.toString(arr));}public static void shellSort(int[] arr){int n = arr.length;// 兩層for循環,外層不斷縮小gap(每次縮小為一半)for(int gap = n / 2; gap > 0; gap /= 2){// 內層對每組進行插入排序// 這里的i還是指向第一個待插入元素(也就是gap,可以看圖理解)// 此時已排序數組的最后一個元素,就應該是i - gap// 這里i的跨度就不應該是++而是 += gap(配合圖更好理解)for(int i = gap;i < n; i ++){int current = arr[i];       // 當前待插入元素int pre = i - gap;          // 有序部分的最后一個元素下標// 當 i 位置元素大于等于 pre 位置元素時說明已經有序,就繼續i+= gapwhile(pre >= 0){// 已經是正確位置,直接退出循環if(current >= arr[pre]){break;}// 位置不正確,需要尋找正確位置arr[pre + gap] = arr[pre];pre -= gap;}//此時pre下標的值是負數了,將current的值放到pre變量加上一個gap的位置上arr[pre + gap] = current;}}}
}

測試:

原數組:[8, 9, 1, 7, 2, 3, 5, 4, 6, 0]
排序后:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

優化

  • 希爾排序的性能高度依賴于步長序列的選擇。選擇不同的步長序列可能會對排序效率產生影響。
  • 一些常見的步長序列包括希爾步長序列(h = n/2, n/4, n/8, …)、Sedgewick步長序列等。
  • 通過嘗試不同的步長序列,可以選擇合適的步長來優化希爾排序的性能。

總結

優點

  1. 相對于傳統的插入排序,希爾排序通過將元素分組進行排序,減少了逆序對的數量,從而加快了排序過程。
  2. 希爾排序是原地排序算法,只需在原始數組上進行元素的交換和移動,不需要額外的輔助空間。

缺點

  1. 希爾排序的最壞情況時間復雜度并不穩定,通常在 O(n^2) 到 O(n log n) 之間。雖然平均情況下性能較好,但在某些特定情況下,性能可能不如其他高級排序算法。
  2. 步長序列的選擇對性能產生影響,選擇不當可能導致排序效率下降。

復雜度

  • 時間復雜度:取決于步長序列的選擇,通常在 O(n log n) 到 O(n^2) 之間。
  • 空間復雜度:原地排序,空間復雜度為 O(1)。

使用場景

  1. 希爾排序適用于中等規模的數據集,對于大規模數據,其性能可能不如其他更高級的排序算法。
  2. 在實際應用中,希爾排序的性能可能會比預期的好,尤其在某些特定情況下,例如對部分有序的數據進行排序時。

當使用希爾排序時,應特別注意其時間和空間復雜度的說明是基于最壞情況下的估計。這樣的估計可能會高于實際情況。希爾排序在某些實際應用中可能表現得比預期的要好。

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

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

相關文章

手撕數據結構之棧+例題

目錄 一、棧的概念及結構 二、棧的頭文件及基本框架 三、接口實現 1、對棧的初始化 2、棧的銷毀 3、入棧操作 4、出棧操作 5、判斷棧是否為空 6、返回棧頂元素 7、遍歷棧 四、有效的括號 - 力扣&#xff08;LeetCode&#xff09; 題目描述&#xff1a; 思路&#xff…

靜態網頁和動態網頁區別

1&#xff0c;靜態網頁和動態網頁有何區別 1) 更新和維護 靜態網頁內容一經發布到網站服務器上&#xff0c;無論是否有用戶訪問&#xff0c;這些網頁內容都是保存在網站服務器上的。如果要修改網頁的內容&#xff0c;就必須修改其源文件&#xff0c;然后重新上傳到服務器上。…

k8s-----集群調度

目錄 一&#xff1a;調度約束 二&#xff1a;Pod 啟動創建過程 三&#xff1a;k8s調度過程 1、Predicate 有一系列的常見的算法 2、常見優先級選項 3、指定調度節點 &#xff08;1&#xff09;nodeName指定 &#xff08;2&#xff09;nodeSelector指定 四&#xff1a;親和…

【SA8295P 源碼分析】68 - Android 側用戶層 輸入子系統獲取 /dev/input/event0 節點數據 代碼流程分析

【SA8295P 源碼分析】68 - Android 側用戶層 輸入子系統獲取 /dev/input/event0 節點數據 代碼流程分析 一、EventHub.cpp 監聽 /dev/input/event0 節點流程二、EventHub.cpp 讀取 /dev/input/event0 節點數據流程系列文章匯總見:《【SA8295P 源碼分析】00 - 系列文章鏈接匯總…

C++——繼承

文章目錄 &#x1f99c;1. 什么是繼承&#x1f40a;1.1 概念&#x1f40a;1.2 格式&#x1f40a;1.3 繼承方式 & 訪問限定符 &#x1f426;2. 派生類和基類的賦值問題&#x1f9a9;3. 派生類和基類同名成員問題&#x1f413;4.派生類默認成員函數&#x1f409;4.1 構造函數…

React源碼解析18(1)------ React.createElement 和 jsx

1.React.createElement 我們知道在React17版本之前&#xff0c;我們在項目中是一定需要引入react的。 import React from “react” 即便我們有時候沒有使用到React&#xff0c;也需要引入。原因是什么呢&#xff1f; 在React項目中&#xff0c;如果我們使用了模板語法JSX&am…

使用OkHttp發送POST請求的幾種方式

使用OkHttp發送POST請求的幾種方式 介紹pom依賴基本的POST請求帶授權的POST請求POST方式發送JSON數據Multipart POST 請求 介紹 本文將介紹 OkHttp 客戶端的基本用法。 主要介紹 OkHttp 3.x 版本中發送Post請求的幾種方式。 pom依賴 <dependency><groupId>com.sq…

單調遞增的數字——力扣738

文章目錄 題目描述解法題目描述 解法 #include<iostream> #include<string>using namespace std;int monotoneIncreasingDigits

【學習】若依源碼(前后端分離版)之 “ 異常處理”

大型紀錄片&#xff1a;學習若依源碼&#xff08;前后端分離版&#xff09;之 “ 異常處理” 前言1、統一返回實體定義2、定義登錄異常定義3、基于ControllerAdvice注解的Controller層的全局異常統一處理4、測試訪問請求結語 前言 通常一個web框架中&#xff0c;有大量需要處理…

中小企業項目管理軟件推薦:選擇適合的工具提升項目效率!

中小企業項目管理軟件有哪些&#xff1f;Zoho Projects是一款好用無廣告的項目管理軟件。當個小創業者是真的不容易&#xff0c;不僅要管理團隊&#xff0c;還要管理團隊項目。很多團隊之前用了好多項目管理的軟件&#xff0c;但是都不太滿意。但是如果你經常參加創業者聚會上&…

常見的路由協議之RIP協議與OSPF協議

目錄 RIP OSPF 洪泛和廣播的區別 路由協議是用于在網絡中確定最佳路徑的一組規則。它們主要用于在路由器之間交換路由信息&#xff0c;以便找到從源到目標的最佳路徑。 常見的路由協議&#xff1a; RIP (Routing Information Protocol)&#xff1a;RIP 是一種基于距離向量算…

Mac os 上的apt-get install 就是brew install

Mac os 上面不支持apt-get install ,但是有個 brew install可以代替。 Homebrew是Mac OS的包管理器&#xff0c;可以方便地安裝各種需要的軟件。 1.1 安裝Homebrew 如果沒有安裝Homebrew&#xff0c;需要在終端輸入以下命令進行安裝&#xff1a; /usr/bin/ruby -e "$(…

使用wxPython和PyMuPDF在Python中顯示PDF目錄的實現

展示如何使用wxPython和PyMuPDF庫在Python中選擇PDF文件并將目錄顯示在列表框中。 簡介&#xff1a; 在本篇教程中&#xff0c;我們將學習如何使用wxPython和PyMuPDF庫在Python中選擇PDF文件&#xff0c;并將其目錄顯示在一個列表框中。這將使用戶能夠方便地瀏覽PDF文檔的目錄…

c#實現設配器模式

下面是一個使用C#實現適配器模式的示例代碼&#xff1a; using System;// 目標接口 public interface ITarget {void Request(); }// 目標類 public class Target : ITarget {public void Request(){Console.WriteLine("目標類的請求");} }// 需要適配的類 public c…

Golang 局部變量、全局變量 聲明

文章目錄 一、局部變量二、全局變量 一、局部變量 四種聲明方式 多變量聲明&#xff1a; package mainimport "fmt"//局部變量聲明 func main() {//方法一: 聲明一個變量和數據類型&#xff0c;不初始化值&#xff1b;默認值為0&#xff1b;var lvA intfmt.Printl…

【MybatisPlus】LambdaQueryWrapper和QueryWapper的區別

個人主頁&#xff1a;金鱗踏雨 個人簡介&#xff1a;大家好&#xff0c;我是金鱗&#xff0c;一個初出茅廬的Java小白 目前狀況&#xff1a;22屆普通本科畢業生&#xff0c;幾經波折了&#xff0c;現在任職于一家國內大型知名日化公司&#xff0c;從事Java開發工作 我的博客&am…

可視化應用:提升教育領域的學習與理解

在教育領域&#xff0c;可視化應用作為一種強大的工具&#xff0c;已經開始發揮著重要的作用。通過將抽象的概念和復雜的數據轉化為直觀的圖形和圖表&#xff0c;可視化應用能夠提升學生的學習效果和理解能力。本文將探討可視化應用在教育領域中的重要性&#xff0c;以及它在不…

電路基礎之電容

電容器&#xff08;Capacitor&#xff09;是由兩個導體電極之間夾著一個電介質而組成的元件。這兩個電極可以是金屬板、箔片、涂層等&#xff0c;而電介質則是放置在電極之間的絕緣材料。電容器的基本構成包括以下幾個要素&#xff1a; 電極&#xff1a;電容器的電極是兩個導體…

Ubuntu系統kubeadm安裝K8S_v1.25.x容器使用docker(K8S_v1.24版本以后依然使用docker容器管理)

安裝所需要的全部文檔請點擊這里下載 系統是&#xff1a; rootk8s-master:~# cat /etc/lsb-release DISTRIB_IDUbuntu DISTRIB_RELEASE22.04 DISTRIB_CODENAMEjammy DISTRIB_DESCRIPTION“Ubuntu 22.04.3 LTS” rootk8s-master:~# uname -a Linux k8s-master 5.15.0-76-generi…

js合并數組對象(將數組中具有相同屬性對象合并到一起,組成一個新的數組)

一、根據數組對象中某一key值&#xff0c;合并相同key值的字段&#xff0c;到同一個數組對象中&#xff0c;組成新的數組 1.原數組&#xff1a; var array [{ id: 1, name: Alice },{ id: 2, name: Bob },{ id: 1, age: 25 },{ id: 3, name: Charlie, age: 30 } ];2.合并后數…