【數據結構篇】排序1(插入排序與選擇排序)

注:本文以排升序為例

常見的排序算法:

目錄:

一 直接插入排序:

1.1 基本思想:

1.2 代碼:

1.3 復雜度:

二 希爾排序(直接插入排序的優化):

2.1 基本思想:

2.2 代碼:

2.3 復雜度:

三 直接選擇排序:

3.1 基本思想:

3.2 代碼:

3.3 復雜度:

四 堆排序:


一 直接插入排序:

1.1 基本思想:

直接插入排序是?種簡單的插入排序法,其基本思想是:把待排序的記錄按其關鍵碼值的大小逐個插入到?個已經排好序的有序序列中,直到所有的記錄插入完為止,得到?個新的有序序列。

  • 實際我們玩撲克牌時就用到了這一思想

動圖:

https://i-blog.csdnimg.cn/direct/497745179f75471fb4fa306e4985a731.gif

解釋:當插入第 i(i>=1) 個元素時,前面的 array[0],array[1],…,array[i-1] 已經排好序,此時? array[i] 的排序碼與 array[i-1],array[i-2],… 的排序碼順序進行比較,找到插入位置即將 array[i] 插入,原來位置上的元素順序后移。

1.2 代碼:

//直接插入排序
void InsertSort(int* arr, int n)
{for (int i = 0; i < n-1; i++){int end = i;int tmp = arr[end + 1];while (end >= 0){if (arr[end] > tmp){arr[end + 1] = arr[end];end--;}else{break;}}arr[end + 1] = tmp;}
}

end:指向有序序列的最后一個數據:初始為0,末態為n-2

tmp:有序序列后的第一個待排序數據:初始為1,末態為n-1

以一次循環為例:
將tmp與end位置數據進行比較,

??? 若end處更大,將end位置數據移到end+1處,end--,繼續讓end-1處數據與tmp比較
??? 否則直接跳出循環,此時end+1位置為空,需要放入tmp

最壞的情況:當end為0處數據移到end為1處,此時end變為-1,需要跳出循環,并將tmp放到0處

1.3 復雜度:

元素集合越接近有序,直接插入排序算法的時間效率越高。
1.時間復雜度:O(N^2)

2.空間復雜度:O(1)

二 希爾排序(直接插入排序的優化):

在直接插入排序中我們發現,元素越無序,直接插入排序算法時間效率越低(因為比較次數越多)。特別是當數組為降序,我們要排升序,此時數組的相對無序程度達到了最大,時間復雜度也到了最大。所以D.L.Shell在1959年提出了希爾排序。

希爾排序是基于插入排序的以下兩點性質而提出改進方法的:

????????插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率。

????????但插入排序一般來說是低效的,因為插入排序每次只能將數據移動一位。

2.1 基本思想:

????????希爾排序法又稱縮小增量法。希爾排序法的基本思想是:先選定?個整數(通常是gap=n/3+1),把 待排序?件所有記錄分成各組,所有的距離相等的記錄分在同?組內,并對每?組內的記錄進?排序,然后gap=gap/3+1得到下?個整數,再將數組分成各組,進行插入排序,當gap=1時,就相當于 直接插入排序。它是在直接插入排序算法的基礎上進行改進?來的,綜合來說它的效率肯定是要?于直接插入排序算法的。

以排序數組為例:

2.2 代碼:

//希爾排序
//希爾排序時間復雜度大約為:O(n^1.3)
void ShellSort(int* arr, int n)
{int gap = n;//6while (gap > 1){gap = gap / 3 + 1;//保證最后一次gap一定為1for (int i = 0; i < n - gap; i++){int end = i;//n-gap-1int tmp = arr[end + gap];while (end >= 0){if (arr[end] > tmp){arr[end + gap] = arr[end];end -= gap;}else {break;}}arr[end + gap] = tmp;}}
}

直接插入排序法的改進,其在許多地方有相似之處:

??? 一次預排序
??????? 從下標為0的元素開始,每隔gap-1個數據取數據分到一組,從取數據的方式我們可以得出以下結論:
??????????? 總共有gap組(0-(gap-1)的元素為每一組的頭元素)
??????????? 每組有n/gap或n/gap+1個數據

??????? 每一次排序我們排的是end和end+gap(即tmp)處的元素,保證每次排序都是在同一組內排
??? end初始為0可得tmp初始為gap,tmp末態為n-1可得end末態為n-1-gap
??? 在一組內進行的是直接插入排序,只不過把距離從1換為gap,全部換一下就行了,思路是一樣的,每次預排序結束后,讓gap/3+1,加一保證最后一次排序gap為1,否則無法保證最后一次是直接插入排序

2.3 復雜度:

1.時間復雜度:最好O(N^1.3),最壞O(N^2)

2.空間復雜度:O(1)

三 直接選擇排序:

3.1 基本思想:

1.在元素集合 array[i]–array[n-1] 中選擇關鍵碼最大(小)的數據元素
2.若它不是這組元素中的最后一個(第?個)元素,則將它與這組元素中的最后?個(第?個)元素交換
3.在剩余的 array[i]–array[n-2](array[i+1]–array[n-1]) 集合中,重復上述步驟,直到集合剩余1個元素

動圖:

https://i-blog.csdnimg.cn/direct/7541a586a0fd460ca2f219bd74f36bde.gif

3.2 代碼:

void SelectSort(int* arr, int n)
{int begin = 0;int end = n - 1;while (begin < end){int mini = begin;int maxi = begin;for (int i = begin+1; i <= end; i++){if (arr[mini] > arr[i]){mini = i;}if (arr[maxi] <  arr[i]){maxi = i;}}//mini begin//maxi end//避免maxi begini都在同一個位置,begin和mini交換之后,maxi數據變成了最小的數據if (maxi == begin){maxi = mini;}Swap(&arr[maxi], &arr[end]);Swap(&arr[mini], &arr[begin]);--end;++begin;}
}

1.每次在剩余序列中找最大的和最小的,最大的交換至后面,最小的交換至前面

2.

進入循環,mini找到1,maxi還是在9,此時我們將再將mini和begin交換,maxi與end交換,

end++,begin–跳出循環,排序完成仍然是931,出現了問題。所以需要

if (maxi == begin){maxi = mini;}

這樣當我們將mini和begin交換完成后,maxi所指向的仍然是最大的數據,將其再與end交換

3.3 復雜度:

1.時間復雜度:O(N^2)

2.空間復雜度:O(1)

四 堆排序:

堆排序是指利?堆積樹(堆)這種數據結構所設計的?種排序算法,它是選擇排序的? 種。它是通過堆來進?選擇數據。需要注意的是排升序要建?堆,排降序建?堆。

在 【數據結構篇】順序結構二叉樹(堆)的堆排序已經講過了此方法,這里就不贅述了。

以上就是【數據結構篇】排序1(插入排序與選擇排序)的全部內容,歡迎指正~?🌹🌹🌹

碼文不易,還請多多關注支持,這是我持續創作的最大動力!

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

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

相關文章

Cursor日常配置指南

文章目錄 整體說明一、簡單介紹1.1、簡介1.2、功能 二、日常配置2.1、Profiles 簡介2.2、Cursor 配置2.2.1、通用設置&#xff08;General&#xff09;2.2.2、功能設置&#xff08;Features&#xff09;2.2.2.1、長上下文&#xff08;Large context&#xff09;2.2.2.2、代碼索…

客戶體驗數據使用的三種視角——旅程視角

企業收集到大量的客戶體驗數據之后&#xff0c;應該如何應用&#xff1f;有哪些主要的使用場景和分析視角呢&#xff1f;接下來&#xff0c;體驗家團隊將通過三篇文章陸續介紹體驗數據的三種應用場景&#xff0c;以幫助企業更有效地利用體驗數據進行改進。 這三個場景分別是…

大語言模型怎么進行記憶的

大語言模型怎么進行記憶的 大語言模型(LLM)本身是無狀態的,每次輸入獨立處理,但可通過以下方式實現對話記憶及長期記憶能力: 模型架構改進 顯式記憶模塊: 記憶網絡(Memory Networks) :在模型里嵌入可讀寫的記憶單元,像鍵值存儲 (Key - Value Memory)或動態記憶矩…

Spring Boot 與 RabbitMQ 的深度集成實踐(三)

高級特性實現 消息持久化 在實際的生產環境中&#xff0c;消息的可靠性是至關重要的。消息持久化是確保 RabbitMQ 在發生故障或重啟后&#xff0c;消息不會丟失的關鍵機制。它涉及到消息、隊列和交換機的持久化配置。 首先&#xff0c;配置隊列持久化。在創建隊列時&#xf…

成功案例丨GEZE與Altair合作推動智能建筑系統開發

Altair 作為計算智能領域的全球領導者&#xff0c;將分別在北京、上海、成都、深圳舉辦 “AI驅動&#xff0c;仿真未來”Altair 區域技術交流會。屆時將匯聚行業專家與先鋒企業&#xff0c;共同探討仿真智能化如何賦能工業創新&#xff0c;分享最新仿真與 AI 技術的應用實踐。歡…

DDoS與CC攻擊:誰才是服務器的終極威脅?

在網絡安全領域&#xff0c;DDoS&#xff08;分布式拒絕服務&#xff09;與CC&#xff08;Challenge Collapsar&#xff09;攻擊是兩種最常見的拒絕服務攻擊方式。它們的目標都是通過消耗服務器資源&#xff0c;導致服務不可用&#xff0c;但攻擊方式、威脅程度和防御策略存在顯…

循環中使用el-form

循環中使用el-form 主要是校驗問題 el-table 的數據 :data“ruleForm.tableData” :prop“‘tableData.’ $index ‘.name’” :rules“rules.name” <el-button type"primary" click"addNewData">新增項目</el-button><el-form :model&…

SAP學習筆記 - 開發13 - CAP 之 添加數據庫支持(Sqlite)

上一章學習了CAP開發準備&#xff0c;添加Service。 SAP學習筆記 - 開發12 - CAP 之 開發準備&#xff0c;添加服務-CSDN博客 本章繼續學習CAP開發 - 添加數據庫支持&#xff08;Sqlite&#xff09;。 目錄 1&#xff0c;數據庫準備 - H2 內存數據庫 - Sqlite數據庫 a&…

【數據結構與算法】——圖(三)——最小生成樹

前言 本將介紹最小生成樹以及普里姆算法&#xff08;Prim&#xff09;和克魯斯卡爾&#xff08;Kruskal&#xff09; 本人其他博客&#xff1a;https://blog.csdn.net/2401_86940607 圖的基本概念和存儲結構&#xff1a;【數據結構與算法】——圖&#xff08;一&#xff09; 源…

Flink運維要點

一、Flink 運維核心策略 1. 集群部署與監控 資源規劃 按業務優先級分配資源&#xff1a;核心作業優先保障內存和 CPU&#xff0c;避免資源競爭。示例&#xff1a;為實時風控作業分配專用 TaskManager&#xff0c;配置 taskmanager.memory.process.size8g。 監控體系 集成 Prom…

面試點補充

目錄 1. 搭建lnmp Linux 系統基礎命令 nginx相關命令 MySQL 相關命令 PHP 相關命令 驗證命令 下載并部署 Discuz! X3.4 論壇 到 Nginx 網站 2. 腦裂 2.1 腦裂的定義 2.2 腦裂產生的原因 1. 主備節點之間的心跳線中斷 2. 優先級沖突 3. 系統或服務負載過高 2.3 如何…

天能股份SAP系統整合實戰:如何用8個月實現零業務中斷的集團化管理升級

目錄 天能股份SAP系統整合案例&#xff1a;技術驅動集團化管理的破局之路 一、企業背景&#xff1a;新能源巨頭的數字化挑戰 二、項目難點&#xff1a;制造業的特殊攻堅戰 1. 生產連續性剛性需求 2. 數據整合三重障礙 3. 資源限制下的技術突圍 三、解決方案&#xff1a;S…

嵌入式學習筆記 - STM32獨立看門狗IWDG與窗口看門狗WWDG的區別

下圖說明了獨立看門狗IWDG與窗口看門狗WWDG的區別: 從中可以看出&#xff1a; 一 復位 獨立看門狗在計數器技術導0時復位&#xff0c; 窗口看門狗在計數器計數到0X40時復位。 二 喂狗 獨立看門狗可以在計數器從預裝載值降低到0過過程中的任意時間喂狗&#xff0c; 窗口看…

配電房值守難題終結者:EdgeView智能監控的7×24小時守護

在電力行業數字化轉型的背景下&#xff0c;開關柜中的設備作為電能傳輸過程中的重要一環&#xff0c;其質量及運行狀態直接關系到電網的安全性、可靠性、穩定性和抵抗事故的能力。 然而&#xff0c;在開關柜的調試部署與運行使用階段&#xff0c;也常常會遇到設備標準不統一、…

B樹與B+樹全面解析

B樹與B樹全面解析 前言一、B 樹的基本概念與結構特性1.1 B 樹的定義1.2 B 樹的結構特性1.3 B 樹的節點結構示例 二、B 樹的基本操作2.1 查找操作2.2 插入操作2.3 刪除操作 三、B 樹的基本概念與結構特性3.1 B 樹的定義3.2 B 樹的結構特性3.3 B 樹的節點結構示例 四、B 樹與…

如何使用VCS+XA加密verilog和spice網表

如果要交付verilog&#xff0c;但是需要對方進行VCS仿真&#xff0c;那么可以用以下方法&#xff1a; 一、基于編譯指令的局部加密? ?適用場景?&#xff1a;需精確控制加密范圍&#xff08;如僅加密核心算法或敏感邏輯&#xff09;。 ?實現步驟?&#xff1a; ?代碼標注…

策略模式-枚舉實現

策略模式的實現方法有很多&#xff0c;可以通過策略類if,else實現。下面是用枚舉類實現策略模式的方法。 定義一個枚舉類&#xff0c;枚舉類有抽象方法&#xff0c;每個枚舉都實現抽象方法。這個策略&#xff0c;實現方法是工具類的很實現&#xff0c;代碼簡單好理解 枚舉實現…

大數據hadoop小文件處理方案

Hadoop處理小文件問題的解決方案可分為存儲優化、處理優化和架構優化三個維度,以下是綜合技術方案及實施要點: 一、存儲層優化方案 1.文件合并技術 離線合并:使用hadoop fs -getmerge命令將多個小文件合并為大文件并重新上傳; MapReduce合并:開發專用MR…

線程調度與單例模式:wait、notify與懶漢模式解析

一.wait 和 notify&#xff08;等待 和 通知&#xff09; 引入 wait notify 就是為了能夠從應用層面&#xff0c;干預到多個不同線程代碼的執行順序&#xff0c;可以讓后執行的線程主動放棄被調度的機會&#xff0c;等先執行的線程完成后通知放棄調度的線程重新執行。 自助取…

ros運行包,Ubuntu20.04成功運行LIO-SAM

zz:~/lio_sam_ws$ source devel/setup.bash zz:~/lio_sam_ws$ roslaunch lio_sam run.launch 創建包鏈接&#xff1a; 鏈接1&#xff1a;Ubuntu20.04成功運行LIO-SAM_ubuntu20.04運行liosam-CSDN博客 鏈接2&#xff1a;ubuntu 20.04 ROS 編譯和運行 lio-sam,并且導出PCD文件…