數據結構 之 【排序】(直接插入排序、希爾排序)

目錄

1.直接插入排序

1.1直接插入排序的思想

1.2直接插入排序的代碼邏輯:?

1.3 直接插入排序圖解?

1.4單趟排序代碼(單個元素的排序邏輯)

1.5完整排序代碼

1.6直接插入排序的時間復雜度與空間復雜度

1.7直接插入排序的優勢?

2.希爾排序(縮小增量排序)

2.1希爾排序的思想

2.2希爾排序的代碼邏輯

2.3希爾排序圖解

2.4單單趟排序代碼(對于特定的gap的一組元素的排序)

2.5單趟排序代碼(對于特定的gap的分組排序)

2.5.1一組排好序再排另一組

2.5.2 根據元素的所在組進行直接插入排序

?2.6完整排序代碼

2.6.1一組排好序再排另一組

?2.6.2 根據元素的所在組進行直接插入排序

2.7希爾排序的時間復雜度與空間復雜度


所有排序的實現皆以升序為例

1.直接插入排序

1.1直接插入排序的思想

直接插入排序的思想就是將待排序的數插入到一組有序的數中

就像打撲克牌摸牌階段,我們一張一張摸牌并整理有序的過程就是直接插入排序的過程?

1.2直接插入排序的代碼邏輯:?

創建 end 變量,初始化為有序數組中最后一個數的下標

創建 tmp變量,初始化為待排序的數值

然后將 tmp變量 與 end位置的數 從后向前 依次比較,按需要(升降序)挪動與存放數據

1.3 直接插入排序圖解?

如果?tmp 比 end位置的數?大tmp 存放在 end + 1 位置?

如果?tmp 比 end位置的數 小先將end位置的數向后移動一位,再 --end

然后繼續將 tmp?與 end位置的數 從后向前 依次比較

如果?tmp 比 end位置的數?大tmp 存放在 end + 1 位置?

(1) 依次比較,這顯然是一個循環

(2) tmp可能比所有值都小,即 end 可能 小于0 (數組下標的角度),這可以作為循環結束條件

(3) 實現正確的情況下, tmp 永遠存放在 end + 1 位置

1.4單趟排序代碼(單個元素的排序邏輯)

int end;
int tmp;
while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];--end;}else break;
}
a[end + 1] = tmp;

tmp 比 end位置的數 小一直挪動數據并--end

tmp 比 end位置的數 大 就跳出循環

因為我們知道 (實現正確下) tmp 永遠放在 end + 1 位置

選擇在循環外面控制 tmp 存放的位置可以解決?end<0 與 end >= 0兩種情況

end >= 0,即 tmp 不存放在數組中首元素的位置

end < 0,即 tmp 比 所有數組元素都要小,不斷--end,直到循環結束,最終放在第一個位置

1.5完整排序代碼

void InsertSort(int* a, int n){ for(int i = 0; i < n - 1; ++i){int end = i;int tmp = a[i + 1];while (end >= 0){if (tmp < a[end]){a[end + 1] = a[end];--end;}else break;}a[end + 1] = tmp;}
}

在單趟排序的基礎上控制end與tmp即可完整代碼

一個數我們可以看作是有序的,所以 end初始值應為0,tmp初始值為數組中的第二個數

一趟比較完畢,前兩個數有序了,end位置往后挪,tmp被賦值為下一個數

這顯然也是一個循環........

1.6直接插入排序的時間復雜度與空間復雜度

直接插入排序的最壞情況就是輸入數組完全逆序

假設數組有N個元素,即

第1次插入操作(從第2個元素(索引1)開始插入):前1個已排序元素一共后移1次

第2次插入操作:前2個已排序元素一共后移2次

第3次插入操作:前3個已排序元素一共后移3次

.........

第 N - 1 次插入操作:前N - 1 個已排序元素一共后移N - 1 次

那么移動總次數就是 ((N - 1)* N)/ 2?

所以時間復雜度就是 O(N^2)

?直接插入排序創建的變量只有i、end、tmp,變量的數量固定,所有操作均在原數組上完成

所以空間復雜度為O(1)

1.7直接插入排序的優勢?

元素集合越接近有序,直接插入排序算法的時間效率越高

2.希爾排序(縮小增量排序)

2.1希爾排序的思想

希爾排序的思想就是通過分組直接插入排序縮小增量(gap)的操作改進普通的直接插入排序

2.2希爾排序的代碼邏輯

將間隔大小為gap(初始值一般為n/2、n/3+1)的數組元素看作一組,每組進行直接插入排序,然后縮小gap(n/2/2、(n/3+1)/3+1),再進行直接插入排序,縮小gap再排序.....

一直到gap為1的直接插入排序完成截止

顯然這是循環套循環,因為gap不斷縮小而對于每個具體的gap來說又需要進行直接插入排序

2.3希爾排序圖解

循環開始,gap初始值為n/2,直接插入排序完成后,gap /= 2,再一次直接插入排序完成后,gap/=2,此時gap縮小至1,此次直接插入排序完成后,數組有序

gap必須縮小至1,才能保證數組有序

gap也可以是 gap = gap / 3 + 1,+1是為了gap最終可縮小至1

gap /= 2不用+1 因為式子本身可以確保gap縮小至1

2.4單單趟排序代碼(對于特定的gap的一組元素的排序)

        int gap;int end;int tmp;while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else    break;}a[end + gap] = tmp;}
}

相對于直接插入排序,單單趟的變化簡單來說就是移動間隔從1變為了gap

2.5單趟排序代碼(對于特定的gap的分組排序)

2.5.1一組排好序再排另一組

int gap;
gap /= 2;
for(int j = 0; j < gap; ++j){for (int i = j; i < n - gap; i += gap){int end = i;int tmp = a[i + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else    break;}a[end + gap] = tmp;}
}

內層for循環控制的是特定的某一組數組元素的end與tmp的變化值

兩者間隔為gap,end初始值為i,tmp為其后gap個位置的值,所以i+gap<n,即i < n - gap

因為是先排好一組再排另外一組,所以需要 i+=gap

外層for循環控制的是每一組數組元素的end的初始值?

假設數組一共有n個元素,將間隔大小為gap的數組元素視為一組,那么每一組數組元素的end的初始值 一定 大于等于零小于gap(下標從零開始)

2.5.2 根據元素的所在組進行直接插入排序

int gap;
gap /= 2;
for (int i = 0; i < n - gap; ++i){int end = i;int tmp = a[i + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else    break;}a[end + gap] = tmp;
}

遍歷數組元素,根據元素的所在組進行直接插入排序

?for循環控制的是數組元素的end與tmp的變化值

兩者間隔為gap,end初始值為i,tmp為其后gap個位置的值,所以i+gap<n,即i < n - gap

通過 ++i 就可實現遍歷數組并根據元素的所在組進行直接插入排序的操作

?2.6完整排序代碼

2.6.1一組排好序再排另一組

void ShellSortUp2(int* a, int n)
{int gap = n;while (gap > 1){gap /= 2;for(int j = 0; j < gap; ++j){for (int i = j; i < n - gap; i += gap){int end = i;int tmp = a[i + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else    break;}}a[end + gap] = tmp;}}}
}

通過將gap初始化為n,并將gap大于1作為循環結束條件,可以避免單個數的排序現象

再在循環內部將gap/2,也不遲

?2.6.2 根據元素的所在組進行直接插入排序

void ShellSortUp1(int* a, int n)
{int gap = n;while(gap > 1){gap /= 2;for (int i = 0; i < n - gap; ++i){int end = i;int tmp = a[i + gap];while (end >= 0){if (tmp < a[end]){a[end + gap] = a[end];end -= gap;}else    break;}a[end + gap] = tmp;}}
}

通過將gap初始化為n,并將gap大于1作為循環結束條件,可以避免單個數的排序現象

再在循環內部將gap/2,也不遲

2.7希爾排序的時間復雜度與空間復雜度

希爾排序的兩種實現方式本質上都是分組排序和縮小增量操作,時間復雜度沒差別

時間復雜度完整的推導方式小編也無能為力,

只記得結論為時間復雜度為O(N*logN) ,大約是n^1.3

希爾排序的變量個數固定,所進行的操作在原數組上,所以空間復雜度為O(1)

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

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

相關文章

Laravel 后臺登錄 403 Forbidden 錯誤深度解決方案-優雅草卓伊凡|泡泡龍

Laravel 后臺登錄 403 Forbidden 錯誤深度解決方案-優雅草卓伊凡|泡泡龍一頓操作猛如虎&#xff0c;一看結果250&#xff0c;必須記錄&#xff0c;必須記錄&#xff0c;&#xff01;今天弄了很久關于我們2023年的產品系統蜻蜓T會議系統專業版&#xff0c;然后終于搞好了密碼也重…

Newline全場景方案閃耀2025中國智慧生活大會

7月15日 — 16日&#xff0c;由中國電子視像行業協會等權威機構指導的2025 CIC中國智慧生活大會在京召開。Newline作為視像協會PID分會副會長單位攜全場景智慧辦公解決方案亮相&#xff0c;首席營銷官李宇鵬受邀出席領袖圓桌環節&#xff0c;與騰訊云、京東方、創維、TCL、小猿…

Edge瀏覽器地址欄默認搜索引擎設置指南

前言 Microsoft Edge 瀏覽器允許用戶自定義地址欄默認搜索引擎&#xff0c;只是設置入口隱藏比較深&#xff0c;以版本 137.0.3296.83 (正式版本) (64 位)為例詳細記錄設置地址欄默認搜索引擎步驟&#xff1a; Edge 設置默認搜索引擎步驟 通過設置界面修改 打開Edge設置&#x…

Python eval函數詳解 - 用法、風險與安全替代方案

Python eval函數詳解 - 用法、風險與安全替代方案在Python中&#xff0c;eval() 是一個內置函數&#xff0c;用于解析并執行傳入的字符串形式的表達式。它能夠將字符串動態地轉換為有效的Python代碼并運行。雖然 eval() 功能強大&#xff0c;但其使用也伴隨著潛在的安全風險。本…

Webpack5 新特性與詳細配置指南

一、Webpack5 新特性 內置 Asset Modules&#xff08;資源模塊&#xff09; 替代 file-loader、url-loader、raw-loader 等&#xff0c;統一資源處理方式。四種類型&#xff1a;asset/resource&#xff1a;導出文件 URL&#xff08;等同 file-loader&#xff09;。asset/inli…

籠子在尋找一只鳥:解讀生活的隱形陷阱

想象一個閃閃發光的籠子&#xff0c;敞開著門&#xff0c;在世界中游蕩&#xff0c;尋找一只鳥兒。這畫面是不是有點奇怪&#xff1f;這是卡夫卡的格言“一個籠子在尋找一只鳥”帶給我們的奇思妙想。通常&#xff0c;鳥兒自由翱翔&#xff0c;籠子靜靜等待&#xff0c;但卡夫卡…

低空經濟展 | 約克科技攜小型化測試設備亮相2025深圳eVTOL展

全球低空經濟與eVTOL產業盛會——2025深圳eVTOL展&#xff0c;將于2025年9月23日至25日在深圳坪山燕子湖國際會展中心盛大啟幕&#xff01; 本屆展會以“低空經濟eVTOL航空應急救援商載大型無人運輸機”為核心&#xff0c;預計匯聚200位發言嘉賓、500家頂尖展商及15,000位專業觀…

數學專業轉行做大數據容易嗎?需要補什么?

高考志愿選擇數學專業是一個面向未來的決定。數學作為基礎學科&#xff0c;其嚴謹的邏輯訓練和抽象思維能力培養&#xff0c;為后續專業發展提供了廣泛的可能性。在數字化時代背景下&#xff0c;數學專業畢業生在數據科學、人工智能等領域的競爭優勢明顯。大學期間推薦考CDA數據…

物聯網系統中-設備管理定義方法

物聯網系統中的設備管理是指對聯網物理設備進行全生命周期監控、配置、維護和優化的系統性過程。它涵蓋了從設備接入到退役的各個環節&#xff0c;是物聯網平臺的核心能力&#xff0c;確保設備安全、穩定、高效地運行并產生價值。 以下是設備管理的詳細定義與核心組成部分&…

java和ptyhon對比

&#x1f4dd; ?1. 語言特性對比??維度??Java??Python??語法風格?靜態類型&#xff0c;需顯式聲明變量類型&#xff1b;代碼冗長&#xff08;需分號、大括號&#xff09;動態類型&#xff0c;變量類型自動推斷&#xff1b;簡潔&#xff08;縮進代替大括號&#xff0c…

UI測試解決方案TestComplete:助力小團隊端到端測試全覆蓋

面對軟件多平臺部署的復雜環境與有限的人力資源&#xff0c;小團隊在追求端到端測試覆蓋時常常陷入困境&#xff1a;既要確保應用在Windows、macOS、Linux及iOS、Android等碎片化平臺上的穩定兼容&#xff0c;又要應對腳本重復編寫耗時費力、測試效率低下的挑戰&#xff0c;同時…

【Android】事件、繪制坐標系相關

一&#xff0c;事件坐標系即MotionEvent事件下發的坐標系&#xff0c;其坐標軸如下MotionEvent#offsetLocation方法可調整坐標原點&#xff0c;以影響MotionEvent#getX&#xff0c;MotionEvent#getY值&#xff0c;以匹配子View的坐標參考系&#xff0c;進而進行事件處理。注意&…

本地Linux服務器使用Docker快速部署SyncTV

文章目錄前言1. Docker部署2. 簡單使用演示3. 安裝cpolar內網穿透4. 配置公網地址5. 配置固定公網地址前言 當想和異地戀人同步看恐怖片卻因網絡延遲錯過驚悚瞬間&#xff0c;或與朋友組隊觀看電競直播時無法實時吐槽…這些尷尬場景或許你都經歷過。而SyncTV的存在正是為了解決…

搭建比分網服務器怎么選數據不會卡頓?

一、 體育比分網站的獨特技術挑戰體育比分網站是互聯網服務中的"極限運動"&#xff0c;面臨三大技術高峰&#xff1a;數據實時性&#xff1a;NBA最后2分鐘的比分延遲超過1秒就會流失用戶流量脈沖&#xff1a;歐冠決賽時流量可能是平時的50-100倍全球覆蓋&#xff1a;…

7月18日總結

bashupload / upload files from command line 遠程文件包含 介紹一個上傳文件的網站 bashupload.com 簡介 借助bashupload.com&#xff0c;可以簡樸地從下令行上傳文件&#xff0c;剖析給其他的服務器&#xff0c;桌面和移動裝備&#xff0c;最大支持25G。上傳的文件會被保留…

【leetcode】3202. 找出有效子序列的最大長度(2)

文章目錄題目題解題目 3202. 找出有效子序列的最大長度&#xff08;2&#xff09; 給你一個整數數組 nums 和一個 正 整數 k 。 nums 的一個 子序列 sub 的長度為 x &#xff0c;如果其滿足以下條件&#xff0c;則稱其為 有效子序列 &#xff1a; (sub[0] sub[1]) % k (su…

Linux內核網絡棧深度剖析:inet_connection_sock.c的服務器端套接字管理

引言 在Linux網絡協議棧中,net/ipv4/inet_connection_sock.c是實現面向連接協議(如TCP)服務器端邏輯的核心文件。它承載了從端口綁定、連接接受到資源回收的全流程管理,是構建高并發網絡服務的基石。本文將深入解析其關鍵機制和實現原理。 一、地址匹配:端口沖突檢測的基…

機器學習中核心評估指標(準確率、精確率、召回率、F1分數)

混淆矩陣混淆矩陣是一個表格&#xff0c;用于總結分類模型在測試集上的預測結果&#xff0c;特別是當真實標簽已知時。它將預測結果分為四種情況&#xff08;記憶&#xff1a;實際和預測一致為True&#xff0c;預測為正是Positive&#xff09;&#xff1a;真正例&#xff1a; 實…

從零搭建Cloud Alibaba

1.初始環境的搭建 1.1環境要求&#xff1a; Spring Boot 3.2.5&#xff1a; 基于最新的 Spring Framework 6.x。支持現代化開發模式&#xff0c;幫助開發更加高效。 JDK 17 或更高版本&#xff1a; Spring Boot 3.x 開始要求 Java 17 作為最低運行環境。 Spring Boot 與 Sp…

Spring AI 工具調用

文章目錄簡述工具定義工具上下文直接返回方法&#xff1a;直接返回工具執行框架控制工具執行用戶控制的工具執行異常處理簡述 工具調用&#xff08;也稱為函數調用&#xff09;是 AI 應用程序中的一種常見模式&#xff0c;允許模型與一組 API 或工具進行交互&#xff0c;從而增…