[數據結構] 基于選擇的排序 選擇排序堆排序

標題:[數據結構] 基于選擇的排序 選擇排序&&堆排序

@水墨不寫bug


(圖片來源于網絡)


目錄

(一)選擇排序

實現:(默認從小到大排序)

優化后實現方法:

(二)堆排序

實現: (從小到大排序)


?

正文開始:

(一)選擇排序

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

????????空間復雜度:O (1)

????????穩定性:不穩定

基本思想:

? ? ? ? 每次從待排序的數據元素中選出一個最大(或最小)的一個元素,存放在序列的起始位置,直到數據有序。

實現:(默認從小到大排序)


void SelectSort(vector<int>& nums)
{int n = nums.size();int begin = 0, end = n - 1;for (int j = 0; j < n-1; ++j){int maxi = 0;for (int i = 0; i < n-j; ++i){if (nums[maxi] < nums[i]){maxi = i;}}swap(nums[end--], nums[maxi]);}
}

選擇排序仍然有一種優化方法:

? ? ? ? 每次選擇的時候,可以同時選擇兩個數,這樣就可以減少遍歷的次數,提高效率。

優化后實現方法:


void SelectSort(vector<int>& nums)
{int n = nums.size();int begin = 0, end = n - 1;while(begin < end){int maxi = begin, mini = begin;for (int i = begin; i <= end; ++i){if (nums[maxi] < nums[i]){maxi = i;}if (nums[mini] > nums[i]){mini = i;}}swap(nums[mini], nums[begin]);if (maxi == begin){maxi = mini;}swap(nums[maxi], nums[end]);begin++;end--;}
}

?但是這種實現方法會導致一個問題:

? ? ? ? 由于每次選兩個值,當最大值下標就是區間左端點時,由于需要將最小值放在左端點,這樣會使最大值下標失效于是就需要修正最大值下標:

? ? ? ? 當最小值下標與區間左端點begin交換后,判斷最大值下標是否指向區間左端點,如果是,則將其修正為交換后的最小值下標的位置。

下標交換只有四種情況:

其實這個問題的本質是:

? ? ? ? 將最小值交換到最前面的操作是先進行的,先進行的過程會對后進行的過程產生干擾。

? ? ? ? 最小值下標與區間左端點交換導致的最大值下標失效的問題,需要修正最大值下標。

(二)堆排序

?堆排序實現過程:默認排升序

????????時間復雜度:O(N*logN)

????????空間復雜度:O(1)

????????穩定性:不穩定

? ? ? ? 特點:小堆排降序,大堆拍升序。

? ? ? ? 小堆可以得到最小的數,然后將最小的數排除,在剩余的數中再次找到最小的數,依次類推;大堆類似。

實現原理:

? ? ? ? 用到了向下調整法建堆的過程:以大堆排升序為例

? ? ? ? 一般堆是由連續的數組模擬實現的邏輯結構,每次將堆頂最大的數移動到數組末尾后,需要向下調整來保持堆的特性。在向下調整之后,最大值就到了數組的末尾,堆也保持了其特性,接下來繼續重復即可。

實現: (從小到大排序)


void AdgustDown(vector<int>& nums,int pos,int size)
//排序的過程size是變化的,動態的,每完成一個數據,size要動態減小
{int n = size;int parent = pos;//find max childint child = pos * 2 + 1;while (child < n){//假設左孩子大if (child + 1 < n && nums[child] < nums[child + 1]){child++;}if (nums[parent] < nums[child]){swap(nums[parent], nums[child]);parent = child;child = parent * 2 + 1;}else{break;}}
}
//大堆排升序
void HeapSort(vector<int>& nums)
{int n = nums.size();//建堆過程for(int i = (n-1-1)/2;i >= 0;--i){ AdgustDown(nums, i,n);}Print(nums);//排序過程for(int j = 0; j < n;++j){int size = n - 1 - j;swap(nums[0], nums[size]);AdgustDown(nums, 0, size);}
}
int main()
{vector<int> nums = { 99,0,7,5,44,3,78,653,90,81 };Print(nums);HeapSort(nums);Print(nums);return 0;
}

完~

未經作者同意禁止轉載?

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

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

相關文章

【Java】垃圾回收學習筆記(二):分代假說與垃圾回收算法

文章目錄 0. 分代收集理論分代假說分代GC定義 1. 垃圾回收算法1.1 標記清除&#xff08;Mark-Sweep&#xff09;算法優點缺點 1.2 標記復制算法優點缺點為什么是8:1:1&#xff1f; 1.3 標記整理算法優點缺點 2. 是否移動&#xff1f;Reference 0. 分代收集理論 分代假說 現在…

Navicat和MySQL的安裝

1、下載 Navicat Navicat 官網&#xff1a;www.navicat.com.cn/ 在產品中可以看到很多的產品&#xff0c;點擊免費試用 Navicat Premium 即可&#xff0c;是一套多連數據庫開發工具&#xff0c;其他的只能連接單一類型數據庫 點擊試用 選擇系統直接下載 二、安裝 Navicat 安…

代碼江湖:Python 中的進程與線程

大家好&#xff0c;我是闊升。今天&#xff0c;咱們來聊聊 Python 中的兩個"老熟人"——進程和線程。這兩個概念可以說是 Python 多任務編程中的"雙子星"&#xff0c;既相似又不同&#xff0c;讓不少小伙伴們頭疼不已。不過別擔心&#xff0c;今天我們就來…

element el-table實現表格動態增加/刪除/編輯表格行,帶校驗規則

本篇文章記錄el-table增加一行可編輯的數據列&#xff0c;進行增刪改。 1.增加空白行 直接在頁面mounted時對form里面的table列表增加一行數據&#xff0c;直接使用push() 方法增加一列數據這個時候也可以設置一些默認值。比如案例里面的 產品件數 。 mounted() {this.$nextTi…

latex 使用 thanks 首頁空白 問題

寫IEEE journal的時候遇到的問題……用latex寫了\thanks&#xff0c;編譯的論文第一頁是空的&#xff0c;這是因為\thanks要在\author內部&#xff0c;然后再用\maketitle&#xff0c;即\author{… \thanks{}}。這樣的話詳細信息就會出現在論文首頁的左下角 另外&#xff0c;\…

linux創建定時任務

crontab方式 先查看是否有cron systemctl status crond 沒有的話就安裝 yum install cronie 打開你的crontab文件進行編輯。使用以下命令打開當前用戶的crontab文件&#xff1a; crontab -e * * * * * /export/test.sh >> /export/test.log 2>&1/export/test.s…

差分算法中的F 和CR參數

自查使用。。F 類似梯度的大小 兩者都用于種群中新個體的生成

leetcode--從中序與后序遍歷序列構造二叉樹

leeocode地址&#xff1a;從中序與后序遍歷序列構造二叉樹 給定兩個整數數組 inorder 和 postorder &#xff0c;其中 inorder 是二叉樹的中序遍歷&#xff0c; postorder 是同一棵樹的后序遍歷&#xff0c;請你構造并返回這顆 二叉樹 。 示例 1: 輸入&#xff1a;inorder …

Unity插件 Unitask學習日志

Unity插件 Unitask學習日志 下載地址 https://github.com/Cysharp/UniTask點擊這里可以查閱中文文檔 在Unity 2020,2021 中使用UPM下載會找不到&#xff0c;可以使用2022版本的unity可以在upm中找到。 安裝方式&#xff1a; 下載zip之后解壓&#xff0c; 復制Plugins 到Uni…

uniapp小程序使用webview 嵌套 vue 項目

uniapp小程序使用webview 嵌套 vue 項目 小程序中發送 <web-view :src"urlSrc" message"handleMessage"></web-view>export default {data() {return {urlSrc: "",};},onLoad(options) {// 我需要的參數比較多 所以比較臃腫// 獲取…

01. 數組篇(進行中......)

一. 前綴和技巧 &#xff08;1&#xff09;前綴和 前綴和技巧適用于快速、頻繁地計算一個索引區間內的元素之和。 class NumArray { public:vector<int> preSum; //前綴和數組NumArray(vector<int>& nums) {//preSum[0] 0&#xff0c;便于計算累加和preSum…

Qt圖形編輯類使用總結—正在編輯中

Qt的圖形編輯通常會涉及以下三個類:QGraphicsView類、QGraphicsScene類及QGraphicsItem類。 QGraphicsView 是構建復雜圖形用戶界面的強大工具,尤其適用于那些需要動態更新、可交互的2D圖形化應用程序,如圖表繪制、流程圖編輯器、游戲地圖顯示等等。通過結合使用 QGraphics…

Spring中的工廠模式詳解及應用示例

1. Spring中的BeanFactory BeanFactory是一個接口&#xff0c;表示它是一個工廠&#xff0c;負責生產和管理bean。在Spring中&#xff0c;BeanFactory是IOC容器的核心接口&#xff0c;定義了管理Bean的通用方法&#xff0c;如 getBean 和 containsBean。 BeanFactory與IOC容器…

Python編程:如何有效等待套接字的讀取與關閉

背景介紹 網絡編程是現代應用程序開發的重要組成部分&#xff0c;尤其是在大數據和實時通信的背景下。套接字&#xff08;Socket&#xff09;作為網絡通信的核心技術&#xff0c;是開發網絡應用程序的基礎。在Python編程中&#xff0c;如何有效地等待套接字的讀取與關閉事件是…

柔性測斜儀:監測鉆孔位移的核心利器

柔性測斜儀&#xff0c;作為一款創新的測量工具&#xff0c;憑借其卓越的設計與性能&#xff0c;在地下建筑、橋梁、隧道及水利水電工程等領域展現出非凡的應用價值。其安裝便捷、操作簡便、高精度及長壽命等特性&#xff0c;使之成為監測鉆孔垂直與水平位移的理想選擇。以下是…

算力共享,分布式大模型是什么,模型并行,流水線并行

目錄 算力共享,分布式大模型是什么 一、算力共享 二、分布式大模型 AllReduce是什么 原理概述 具體原理 簡單例子 模型并行,流水線并行是什么 模型并行 流水線并行 環形通信(如Ring AllReduce)、樹形通信(如Tree AllReduce 環形通信(Ring AllReduce) 樹形通…

【ComfyUI的API接口調用示例】

ComfyUI的API接口調用示例 本文目的 本文調用接口示例主要指導需要調用ComfyUI的開發者如何調用ComfyUI官方的API接口提交任務、查詢歷史、獲取繪畫視頻結果等。 閱讀本文的前提是你本地已經安裝了ComfyUI&#xff0c;并且對工作流繪畫和生成視頻已經有所了解。注意如圖右邊欄…

arm架構安裝chrome

在ARM架構設備上安裝谷歌軟件或應用通常涉及到幾個步驟&#xff0c;這取決于你要安裝的具體谷歌產品&#xff0c;比如谷歌瀏覽器、Google Play服務或者是其他谷歌開發的軟件。下面我會給出一些常見的指導步驟&#xff0c;以安裝谷歌瀏覽器為例&#xff1a; 在Linux ARM64上安裝…

常用的三角函數公式

sin ? 2 x cos ? 2 x 1 \sin ^2 x \cos ^2 x 1 sin2xcos2x1 tan ? x sin ? x cos ? x \tan x \dfrac{\sin x}{\cos x} tanxcosxsinx? cot ? x 1 tan ? x cos ? x sin ? x \cot x \dfrac{1}{\tan x}\dfrac{\cos x}{\sin x} cotxtanx1?sinxcosx? sec …

零基礎做項目---五子棋對戰---day02

用戶模塊 完成注冊登錄&#xff0c;以及用戶分數管理~使用數據庫來保存上述用戶信息. 使用 MyBatis來連接并操作數據庫了 主要步驟: 1.修改 Spring的配置文件,使數據庫可以被連接上. 2.創建實體類&#xff0c;用戶, User 3.創建Mapper接口~ 4.實現MyBatis 的相關xml配置…