數據結構 之 【排序】(直接選擇排序、堆排序、冒泡排序)

目錄

1.直接選擇排序

1.1直接選擇排序的思想

1.2直接選擇排序的代碼邏輯

1.3完整排序代碼

1.3.1一次只選一個最值

1.3.2一次篩選出兩個最值

1.4直接選擇排序的時間復雜度與空間復雜度

2.堆排序

2.1堆排序的思想

2.2堆排序的具體步驟

2.3堆排序圖解

2.4完整排序代碼

3.冒泡排序

3.1冒泡排序的思想

3.2冒泡排序圖解

3.3單趟排序代碼(一輪遍歷進行的操作)?

3.4完整排序代碼

3.5冒泡排序的時間復雜度與空間復雜度


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

1.直接選擇排序

1.1直接選擇排序的思想

直接選擇排序的思想就是對數組進行多輪遍歷,在每一輪遍歷中,從當前未排序部分的元素里選出最大值或最小值,然后依據排序要求,將該最大值或最小值與未排序部分的起始位置或末尾位置的元素進行交換,從而逐步確定數組中各元素的最終位置,最終實現數組有序

1.2直接選擇排序的代碼邏輯

就是根據思想:遍歷+篩選

1.3完整排序代碼

1.3.1一次只選一個最值

void SelectSortUp1(int* a, int n){for(int j = 0; j < n - 1; ++j){int min = j;for (int i = j + 1; i < n; ++i){if (a[i] < a[min])min = i;}Swap(&a[j], &a[min]);}
}

以升序為例,一次遍歷(對未排序部分的遍歷)選出的最小值放在未排序部分的起始位置

內層循環進行的是特定的某一次遍歷的篩選過程

外層循環控制了每次遍歷時的起始位置以及交換過程

1.3.2一次篩選出兩個最值

void SelectSortUp2(int* a, int n){int left = 0, right = n - 1;while(left < right){int min = left, max = left;for (int i = left + 1; i <= right; ++i){if (a[i] < a[min])min = i;if (a[i] > a[max])max = i;}Swap(&a[min], &a[left]);if (left == max)max = min;Swap(&a[max], &a[right]);++left;--right;}
}

對思想進行精進,一次遍歷,選出未排序部分的最大和最小值,按需將其放在對應位置

leftright 控制的是未排序部分的區間大小

一次遍歷選出最大最小值后,以升序為例,

最小值放在未排序部分的起始位置,最大值放在未排序部分的末尾

然后縮小區間

1.4直接選擇排序的時間復雜度與空間復雜度

假設數組有N個元素,一次只選出一個最值,則最壞情況下,第一輪遍歷需遍歷N個元素,第二輪遍歷序遍歷N-1個元素.............第N-1輪遍歷需遍歷2個元素,遍歷結束,遍歷次數為((N+2)*(N-1))/2

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

一次篩選出兩個最值,則最壞情況下,第一輪遍歷大約需遍歷N個元素,第二輪遍歷需遍歷N-2個元素.............一共約遍歷N/2輪,遍歷次數為 ((2+N)*N)/ 2,時間復雜度為O(N^2)

直接選擇排序的變量個數固定,所有操作均在原數組上,所以空間復雜度為O(1)?

2.堆排序

關于堆,可參考前兩期博客? 數據結構 之 【堆】堆的應用

2.1堆排序的思想

數組可以模擬完全二叉樹,堆是一種完全二叉樹,且具備選數的功能,那么

將數組持續變為堆,并對特定的堆選出最值,最終可實現數組有序

2.2堆排序的具體步驟

1.建堆:按需將所給數組變為大(小)堆? ? (建堆的具體步驟參考? 堆的應用 這一期博客)

升序建大堆,降序建小堆

2.交換與調整:以升序為例,建成大堆后,將堆頂元素(為未排序部分的最大值)與末尾位置的元素進行交換,然后對末尾位置之前的所有元素進行向下調整操作,使其再次成為大堆,然后交換堆頂元素與未排序部分的末尾位置的元素,........循環進行調整與交換操作,直到未排序部分的元素個數為1為止

2.3堆排序圖解

2.4完整排序代碼

void AdjustDown(HpDateType* a, int n, int parent){int child = parent * 2 + 1;//有左孩子才進行調整while (child < n)//n是節點個數{//左孩子一個邏輯,右孩子一個邏輯,直接假設//child是左右孩子中較大的一個孩子的下標//注意右孩子的有無(防止越界訪問與無效數據)if (child + 1 < n && a[child] < a[child + 1]){++child;}//與左右孩子中較大的一個孩子進行比較if (a[parent] < a[child]){Swap(&a[parent], &a[child]);parent = child;child = parent * 2 + 1;}else    break;}
}
void HeapSortUp(int* a, int n){//從第一個非葉子節點開始建堆for (int i = (n - 2) / 2; i >= 0; --i){AdjustDwon1(a, n, i);}//堆頂元素與末尾交換,并向下調整//顯然是循環int end = n - 1;while (end > 0){Swap(&a[0], &a[end]);AdjustDwon1(a, end, 0);--end;}
}

通過逐步縮小堆的范圍來排序數組

當堆中只剩一個元素時(即?end = 0),排序過程已完成,?所以 end > 0 作為循環結束條件

2.5堆排序的時間復雜度與空間復雜度

堆排序的時間復雜度O(N*logN),可用最壞情況下的交換次數進行衡量

空間復雜度為O(1)

3.冒泡排序

3.1冒泡排序的思想

進行多輪遍歷,每輪遍歷中,依次比較相鄰元素,若不符合目標順序(升序則前大后小,降序則前小后大),就交換它們的位置。如此,每輪遍歷會將當前未排序部分的最大(小)值“冒泡”到數組一端。當某一輪遍歷無元素交換時,排序完成

3.2冒泡排序圖解

3.3單趟排序代碼(一輪遍歷進行的操作)?

for (int j = 0; j < n - 1; ++j){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);}
}

上述代碼展示的是第一次遍歷進行的操作,數組元素兩兩進行比較,j + 1 < n,所以 j < n - 1

因為是升序,前一個數比后一個數大就交換

3.4完整排序代碼

void BubbleSortUp(int* a, int n){//一趟只正確放好一個數//n個數n - 1 趟for(int i = 0; i < n - 1; ++i){//經過一趟少一次比較for (int j = 0; j < n - 1 - i; ++j){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);}}}
}

冒泡排序遍歷一輪可正確放好一個數組元素,則有n個數組元素的數組只需遍歷n-1輪

冒泡排序遍歷一輪可正確放好一個數組元素,那么遍歷一輪可減少一次比較次數

小優化

內層循環未進行交換操作則證明數組有序,此時可終止循環,減少不必要的循環操作

void BubbleSortUp(int* a, int n){//一趟只正確放好一個數//n個數n - 1 趟for(int i = 0; i < n - 1; ++i){int flag = 0;//經過一趟少一次比較for (int j = 0; j < n - 1 - i; ++j){if (a[j] > a[j + 1]){Swap(&a[j], &a[j + 1]);flag = 1;}}if (!flag)break;}
}

3.5冒泡排序的時間復雜度與空間復雜度

?假設數組有N個元素,則最壞情況下,第一輪遍歷需交換N-1次,第二輪遍歷需交換N-2次,

.............第N-1輪遍歷需交換1次,交換總次數為 ((N-1)*N) / 2, 時間復雜度為O(N^2)

變量個數固定,所有操作均在原數組上,空間復雜度為O(1)?

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

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

相關文章

用手機當外掛-圖文并茂做報告紀要

前陣參加一個峰會,看到演講嘉賓每翻一頁PPT,下面的觀察就舉起手機一頓拍。實話說這種拍下來的,難說還會拿出來看,而且再看的時候也未必能對應到當時主講人的一些解釋 。 如果現場將圖片保存到筆記本電腦,并快速記錄關鍵信息,這樣聽完一個報告可能就直接輸出一篇報道了。 有…

Vue的ubus emit/on使用

這段代碼是 Vue.js 組件中的 mounted 生命周期鉤子函數&#xff0c;主要作用是監聽一個名為 “macSelectData” 的全局事件。具體行為如下&#xff1a;分步解釋&#xff1a;mounted() 生命周期鉤子 當組件被掛載到 DOM 后&#xff0c;Vue 會自動調用 mounted() 方法。這里常用于…

rsync報錯解決

問題說明 [rootlocalhost shyn]# rsync -avz --checksum "root192.168.159.133:/tmp/shyn" "/tmp /shyn"WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! …

ArKTS: DAL,Model,BLL,Interface,Factory using SQLite

HarmonyOS 用ohos.data.rdb 用DBHelper.ets 共用調用SQLite 庫&#xff0c;進行DAL,Model,BLL,Interface,Factory 框架模式&#xff0c;表為CREATE TABLE IF NOT EXISTS signInRecord ( id INTEGER PRIMARY KEY AUTOINCREMENT, employeeId TEXT NOT NULL, employeeName TEXT NO…

MySQL JSON 數據類型用法及與傳統JSON字符串的對比 JSON數據類型簡介

文章目錄前言1. 基本用法JSON數據類型 vs 傳統JSON字符串1. 存儲方式2. 查詢方式對比3. 索引支持JSON存儲對象和數組的性能考慮1. 存儲對象2. 存儲數組性能對比總結最佳實踐建議前言 MySQL從 5.7 版本開始引入了 JSON 數據類型&#xff0c;專門用于存儲 JSON 格式的數據。與傳…

C++:list(1)list的使用

list的使用一.list基本的結構1.環狀雙向鏈表2.哨兵節點3.迭代器4.節點結構5.鏈表遍歷6.迭代器失效二.list的基本使用1.test01函數&#xff1a;主要測試std::list的初始化方式及遍歷2.test02函數&#xff1a;主要測試std::list的常用成員函數操作3.測試結果如下三.list的其他操作…

ArcGIS地形起伏度計算

地形起伏度計算地形起伏度步驟1&#xff1a;計算最大值。步驟2&#xff1a;計算最小值。步驟3&#xff1a;計算地形起伏度。地形起伏度、地形粗糙度、地表切割深度和高程變異系數均為坡面復雜度因子&#xff0c;是一種宏觀的地形信息因子&#xff0c;反映的是較大的區域內地表坡…

llama factory新手初步運行完整版

1、新建conda環境名稱為llama_factory&#xff0c;并激活 conda create -n llama_factory python3.10 conda activate llama_factory2、激活后可檢查內部包是否純凈&#xff0c;要確保環境內包較純凈&#xff0c;不然后續安裝對應包會出現一系列水土不服的問題&#xff0c;導致…

Tomcat與JDK版本對照全解析:避坑指南與生產環境選型最佳實踐

&#x1f49d;&#x1f49d;&#x1f49d;歡迎蒞臨我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 持續學習&#xff0c;不斷…

短視頻矩陣的未來前景:機遇無限,挑戰并存

在當今數字化信息飛速傳播的時代&#xff0c;短視頻以其獨特的魅力迅速席卷全球&#xff0c;成為人們獲取信息、娛樂消遣的重要方式之一。短視頻矩陣作為一種高效的內容傳播與運營模式&#xff0c;正逐漸展現出其強大的影響力和潛力。本文將深入探討短視頻矩陣的未來前景&#…

【數據結構】哈希——位圖與布隆過濾器

目錄 位圖&#xff1a; 引入 位圖實現&#xff1a; 位圖的結構 插入數據(標記數據) 刪除數據(重置數據) 查找數據 位圖完整代碼&#xff1a; 位圖的優缺點&#xff1a; 布隆過濾器&#xff1a; 引入 布隆過濾器實現&#xff1a; 布隆過濾器的結構&#xff1a; 插入…

本地運行C++版StableDiffusion!開源應用StableVerce發布

本地運行C版StableDiffusion&#xff01;開源應用StableVerce發布 StableVerse是一個用C開發的本地運行的圖形工具。適合初學者快速入門&#xff1b;適用于辦公室工作人員的文本和圖像制作的小規模計算能力場景。 開源地址&#xff1a;https://github.com/kelvin-luo/StableVer…

OpenLayers 快速入門(七)矢量數據

看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大家&#xff0c;助你少走彎路&#xff01; OpenLayers…

【PTA數據結構 | C語言版】關于堆的判斷

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 將一系列給定數字順序插入一個初始為空的最小堆。隨后判斷一系列相關命題是否為真。命題分下列幾種&#xff1a; x is the root&#xff1a;x是根結點&#xff1b;x and y are siblings&#xff1a…

[CH582M入門第十步]藍牙從機

前言 學習目標: 1、初步了解BLE協議 2、BLE從機代碼解析 3、使用手機藍牙軟件控制CH582M從機LED亮滅一、藍牙介紹 藍牙(Bluetooth)是一種短距離無線通信技術,主要用于設備之間的數據傳輸和通信。它由愛立信(Ericsson)于1994年提出,現由藍牙技術聯盟(Bluetooth SIG)維…

力扣(LeetCode) ——輪轉數組(C語言)

題目&#xff1a;輪轉數組 給定一個整數數組 nums&#xff0c;將數組中的元素向右輪轉 k 個位置&#xff0c;其中 k 是非負數。 示例1&#xff1a; 輸入&#xff1a; nums [1,2,3,4,5,6,7]&#xff0c;k 3 輸出&#xff1a; [5,6,7,1,2,3,4] 解釋&#xff1a; 向右輪轉 1 步:…

Rocky9部署Zabbix7(小白的“升級打怪”成長之路)

目錄 一、關閉防火墻和SElinux和配置安裝源 二、zabbxi服務器配置 1、安裝Zabbix server&#xff0c;Web前端&#xff0c;agent &#xff0c;mysql-server 2、配置mysql數據庫 3、為Zabbix server配置數據庫 4、啟動對應服務 三、登錄zabbix 四、客戶端部署 五、解決中…

python安裝package和pycharm更改環境變量

安裝numpy包 1、找到對應python版本的numpy包的版本 NumPy - News確認適配python版本的numpy&#xff0c;我安裝 的python是3.11所以安裝的numpy是2.2.0 2、修改pip安裝的鏡像源 1、全局修改&#xff1a; pip config set global.index-url https://pypi.tuna.tsinghua.edu.c…

Redis中的setnx命令為什么是原子性的

Redis的SETNX命令是一個原子性操作&#xff0c;這得益于其單線程架構的特性。Redis采用單線程模型&#xff0c;所有命令都在主線程中順序執行&#xff0c;確保每個操作都具有原子性。執行SETNX時&#xff0c;Redis會首先檢查指定key是否存在&#xff1a;若不存在則設置值并返回…

深入解析Hadoop中的EditLog與FsImage持久化設計及Checkpoint機制

HDFS元數據管理概述在HDFS&#xff08;Hadoop Distributed File System&#xff09;的架構中&#xff0c;元數據管理是保證系統可靠性和性能的核心環節。NameNode作為HDFS的主節點&#xff0c;負責維護整個文件系統的命名空間和文件到數據塊的映射關系。這些元數據的高效管理直…