數據結構初階(17)排序算法——非比較排序(計數排序·動圖演示)、排序算法總結

?2.0 十大排序算法

2.5 非比較排序

之前學習的排序算法都是比較排序——借助比較大小,來實現排序。

非比較就是不借助比較大小,來實現排序。——小眾的、局限的

非比較排序大致有這些:計數排序、桶排序、基數排序

桶排序、基數排序在實踐中意義不大,面試也基本上不會考。

計數排序在實踐中有所應用、校招也會有涉及。

2.5.1 計數排序

基本思想

計數排序又稱為鴿巢原理,是對哈希直接定址法的變形應用。

動圖演示

算法步驟

1. 統計相同元素出現次數。

2. 根據統計的結果將序列回收到原來的序列中。

圖解演示。

適合:數據上界、下界差值小(<1000) ——數據范圍集中的數組。

即不管數據大小, 只看數據集不集中。

不做絕對映射——即數據109不必要映射到數組的109位置, 只需要做相對映射。

數組的大小=最大值-最小值+1——找最值:遍歷一遍(還是要比較)。

負數不是問題:min=-5 ——則-5-(-5)=0還是沒問題。

反映射:5 + min = 105。

核心思想不是通過比較來達到有序的,找最值還是需要比較——遍歷一遍O(N)。

代碼實現
//計數排序
void CountSort(int* a, int n)
{//找最值——假設修正法int min = a[0], max = a[0];for (int i = 1; i < n; i++){//如果有更大——就更新一下最大值if (a[i] > max)max = a[i];if (a[i] < min)min = a[i];}//O(N)//0.計算數據范圍int range = max - min + 1;//1.開辟計數數組int* count = (int*)malloc(sizeof(int) * range);if (count == NULL){perror("malloc fail");return;}memset(count, 0, sizeof(int) * range);//也可以在上面直接calloc——不過calloc的底層邏輯本來就是malloc + memset;//2.統計次數——遍歷原數組——count數組相對位置處值++for (int i = 0; i < n; i++){// (1)統計次數的時候“減”min——“對應”下標位置的值++count[a[i] - min]++;}//3.排序——遍歷count數組,將數據映射回原數組// i控制count遍歷、j控制a遍歷int j = 0;for (int i = 0; i < range; i++){//如果count對應位置不為0——為幾走幾次while (count[i]--)    //--k走k-1次;k--走k次{// 直接覆蓋原數組// (2)還原的時候再把min“加”回來,用下標i加回min就是對應的a中的值a[j++] = i + min;}}
}

時間復雜度:arr數組大小N和count數組大小range當中,較大的那個。

  • O(N) 或者 O(range);
  • 或者直接O(N+range);

顯然當范圍range和數據量在同一量級時,計數排序就是最優排序。——O(N)

測試——100萬個數據(空間不大,大概不到1MB = 2^20 ≈ 10^6,整型就是4MB)

void TestOP()
{srand(time(0));//要產生隨機需要一個種子,否則隨機是寫死的偽隨機const int N = 1000000;int* a1 = (int*)malloc(sizeof(int) * N);int* a2 = (int*)malloc(sizeof(int) * N);int* a3 = (int*)malloc(sizeof(int) * N);int* a4 = (int*)malloc(sizeof(int) * N);int* a5 = (int*)malloc(sizeof(int) * N);int* a6 = (int*)malloc(sizeof(int) * N);int* a7 = (int*)malloc(sizeof(int) * N);for (int i = 0; i < N; ++i){//a1[i] = rand() % 100;a1[i] = rand() % N;                    //產生100個數據——大小都在100萬以內//a1[i] = rand();a2[i] = a1[i];a3[i] = a1[i];a4[i] = a1[i];a5[i] = a1[i];a6[i] = a1[i];a7[i] = a1[i];}int begin1 = clock();    //系統啟動到執行到此的毫秒數//InsertSort(a1, N);int end1 = clock();      //系統啟動到執行到此的毫秒數int begin7 = clock();//BubbleSort(a7, N);int end7 = clock();//int begin3 = clock();//SelectSort(a3, N);//int end3 = clock();//ShellSort(a2, N);int begin2 = clock();ShellSort(a2, N);int end2 = clock();int begin4 = clock();HeapSort(a4, N);//QuickSort1(a2, 0, N - 1);int end4 = clock();int begin5 = clock();QuickSort(a5, 0, N - 1);int end5 = clock();//PrintArray(a4, N);int begin6 = clock();MergeSortNonR(a6, N);int end6 = clock();int begin3 = clock();CountSort(a6, N);int end3 = clock();//printf("InsertSort:%d\n", end1 - begin1);//printf("BubbleSort:%d\n", end7 - begin7);printf("ShellSort:%d\n", end2 - begin2);//printf("SelectSort:%d\n", end3 - begin3);printf("HeapSort:%d\n", end4 - begin4);//printf("QuickSort1:%d\n", end4 - begin4);printf("QuickSort:%d\n", end5 - begin5);printf("MergeSort:%d\n", end6 - begin6);printf("CountSort:%d\n", end3 - begin3);free(a1);free(a2);free(a3);free(a4);free(a5);free(a6);free(a7);
}int main()
{//TestInsertSort();//TestBubbleSort();//TestShellSort();//TestSelectSort();//TestQuickSort();//TestMergeSort();//TestCountSort();TestOP();//MergeSortFile("sort.txt");return 0;
}

測試結果。


空間復雜度:

  • O(range)????????——數據越集中,空間復雜度越小
特性總結

計數排序的特性總結

特性

  1. 計數排序在數據范圍集中時,效率很高(幾乎最高),但是適用范圍及場景有限。
  2. 時間復雜度:O( MAX(N,range) )
  3. 空間復雜度:O(范圍)
  4. 穩定性:穩定

局限性

  • 數據要集中;
  • 只適合整型;
  • 有一定空間復雜度;(取決于數據的集中程度)

基數排序:先按個位排、再按十位排、再按百位排、……(只適合整型)

桶排序:把元素按區間分桶、桶內再排序,最后按桶順序一次倒出來。(時間和空間都不占優)


實踐中排序的對象大多都是結構體,所以計數排序在實踐中的應用并不廣泛。

而比較排序是通用的——只要能比較數據大小就能排——整型、浮點型、字符串、結構體……


排序的核心思想還是“比較”

  • 比較排序實用性廣 && 大。
  • 非比較排序就是小眾的 && 局限的,在特定情境下有自己的實踐意義。

3. 排序算法復雜度及穩定性分析

穩定性:一個數組里面相同的數據,在排序前后的相對位置變不變

——只排序整型當然沒有意義(兩個5沒差)
——故計數排序不考慮穩定性
——排序結構體就有意義了(兩個5不一樣)

穩定性的應用:

例1:同樣分數的考試成績,先交卷的同學,在排序時名字排在前面。——需要穩定排序

例2:同分數的同學,數學分數高的排名靠前——先按數學排序,再按總分排序。

最好不要靠背,要注重理解。

(1)三種O(N^2)的排序算法,只有選擇排序不穩定,空間復雜度都是O(1)

時間處理上呈現等差數列——>O(N^2)
空間處理上不開額外空間——>O(1)

直接插入排序:相等的時候選擇插入在后面,就穩定。


直接選擇排序:乍一想感覺穩定,一些書上也說穩定,實際上不穩定。

選min的時候遇到相等(第二個1)就不更新min,可以保證1穩定。
但是在1和3交換后,就沒辦法保證3穩定。


冒泡排序:相鄰比較,大的往后交換,相等就不換——穩定。

(2)一種O(?)的希爾排序,不穩定,空間復雜度O(1)

希爾排序:相同的數據,預排時可能分到不同的組,就不穩定。

(3)三種O(nlogn)的排序算法,只有歸并穩定,只有堆排序空間復雜度O(1)

堆排序可以原地操作,不額外開空間
快速排序是遞歸,有空間復雜度的消耗的——要建立logN層棧幀
歸并排序要建立一個輔助歸并數組tmp

堆排序:舉例說明不穩定——5 5 3,升序建好大堆,把第一個5(最大值)放到最后——不穩定。

快速排序:要把key交換到數組中間,比key小的在左邊,比key大的在右邊,和key相等的則在左邊和右邊都可以。

歸并排序:歸并的時候,取小的尾插到tmp數組,相等的時候優先尾插左區間的數據——穩定。
即:左 <= 右,就尾插左。

  • “三穩四不穩”
  • 只有快速排序、歸并排序有空間復雜度的消耗
  • 只有直接插入排序、冒泡排序、無優化快速排序時間復雜度分最好最壞。
    (因為和數據是否有序有關)

整體看來,作為內排序,歸并排序確實和其他幾個一樣有不錯的效率,但是考慮到其必有O(N)的空間復雜度,相比之下還是快速排序更優。

4.?選擇題練習


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

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

相關文章

VisualStudio2022調試Unity C#代碼步驟

一.VS安裝Unity開發組件按下圖所示安裝Unity開發組件二.附加Unity調試程序2.1 先將Unity進入Play模式2.2 VS選擇附加Unity調試程序菜單2.3 選擇附加的實例三.加入斷點測試Update方法中成功進入斷點

Zabbix【部署 01】Zabbix企業級分布式監控系統部署配置使用實例(在線安裝及問題處理)程序安裝+數據庫初始+前端配置+服務啟動+Web登錄

Zabbix使用 1.下載 2.安裝 2.1 程序安裝 2.2 數據庫初始化 2.3 前端配置 2.4 服務啟動 3.Web登錄 4.總結 安裝說明: 本次安裝為在線安裝,使用數據庫為PostgreSQL。 1.下載 由于是在線安裝,這次不涉及離線安裝包的下載,僅做參考用,點擊跳轉【下載頁面】,下載說明: 版本…

爬機 驗證服務器是否拒絕請求

當訪問XX網站時返回 418 狀態碼時&#xff0c;說明服務器識別到了爬蟲行為并拒絕了請求。這是網站的反爬機制在起作用&#xff0c;我們可以通過模擬瀏覽器行為來繞過基礎反爬。import requestsurl https://cn.bing.com/# 模擬瀏覽器的完整請求頭&#xff0c;包含更多瀏覽器標識…

GaussDB 數據庫架構師修煉(十三)安全管理(3)-數據庫審計

1 數據庫審計作用數據庫審計機制主要通過對SQL操作或其他操作記錄審計日志的方式 &#xff0c;增強數據庫系統對非法操作的追溯及舉證能力 。高斯數據庫提供兩種審計特性 &#xff1a;傳統審計 &#xff0c;統一審計。2 傳統審計傳統審計通過GUC參數配置需要對數據庫的哪些操作…

C語言(11)—— 數組(超絕詳細總結)

Hi&#xff01;冒險者&#x1f60e;&#xff0c;歡迎闖入 C 語言的奇幻異世界&#x1f30c;&#xff01; 我是 ankleless&#x1f9d1;?&#x1f4bb;&#xff0c;和你一樣的闖蕩者&#xff5e; 這是我的冒險筆記打怪升級之路——C語言之路&#x1f4d6;&#xff0c;里面有踩過…

【AI生成+補充】高頻 hql的面試問題 以及 具體sql

以下是高頻HQL面試題及對應SQL示例&#xff0c;涵蓋核心語法、優化技巧和典型場景&#xff0c;可直接用于面試準備&#xff1a; 一、基礎操作與DDL 1. 創建分區表 & 動態插入分區 sql -- 創建外部分區表&#xff08;按日期分區&#xff09; CREATE EXTERNAL TABLE logs…

開源 Arkts 鴻蒙應用 開發(十七)通訊--http多文件下載

文章的目的為了記錄使用Arkts 進行Harmony app 開發學習的經歷。本職為嵌入式軟件開發&#xff0c;公司安排開發app&#xff0c;臨時學習&#xff0c;完成app的開發。開發流程和要點有些記憶模糊&#xff0c;趕緊記錄&#xff0c;防止忘記。 相關鏈接&#xff1a; 開源 Arkts …

Cloudflare Tunnel 使用SAAS回源加速配置教程

在使用 Cloudflare Tunnel 時,通過“主域名+加速域名”的聯動配置,既能隱藏內網 IP,又能優化訪問速度。本文以實際部署場景為例(主域名 zhuyuming.dpdns.org、加速域名 jiasu.dpdns.org),帶你一步步完成內網服務穿透(以 192.168.1.6:5555 網頁服務為例),實操性強,可直…

C++實戰

Ref deepwiki vuecruddllamma.cpp 目標 計劃實現一個C項目&#xff0c;前端用vue&#xff0c;后端用C和llama.cpp。實現可以進行邏輯功能和AI推理。

dify 調用本地的 stable diffusion api生成圖片的工作流搭建

Dify調用本地Stable Diffusion API的工作流搭建指南 核心架構 #mermaid-svg-ce029i4XFKrDzRgU {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ce029i4XFKrDzRgU .error-icon{fill:#552222;}#mermaid-svg-ce029i4XFK…

【Web后端】Django、flask及其場景——以構建系統原型為例

一、Django 和 Flask 簡介 Django 是一個高級 Python Web 框架&#xff0c;提供了完整的“開箱即用”功能&#xff0c;包括 ORM、認證、管理后臺等&#xff0c;便于快速開發安全且可維護的網站。Flask 是一個輕量級 Python Web 框架&#xff0c;核心功能比較簡單&#xff0c;但…

飛算JavaAI:從智能調度到出行服務的全鏈路技術升級

免責聲明&#xff1a;此文章所有內容都是實驗測試數據 目錄一、智慧交通核心場景的技術突破1.1 交通態勢感知與智能預警系統1.2 公共交通智能調度系統1.3 一體化出行服務系統二、智慧交通系統效能升級實踐2.1 交通數據中臺構建結語&#xff1a;重新定義智慧交通技術邊界一、智慧…

vscode的wsl環境,ESP32驅動0.96寸oled屏幕

注意大小寫&#xff0c;wsl&#xff08;也就是linux環境&#xff09;嚴格區分大小寫。有幫助記得訂閱專欄點贊&#xff0c;當前不定期持續更新。 一、文件夾格式&#xff1a; project/ # 項目根目錄 ├─ main/ # 主程序文件夾 │ ├─ mai…

CodeBuddy AI Coding 企業場景落地實踐與思考

&#x1f449;目錄1 引言2 診斷團隊研發流程3 選擇合適的 AI CODING 工具4 團隊 AI 研發流程落地實踐5 全面 CodeBuddy &#xff0c;深入 CodeBuddy6 誠邀共建在 AI 浪潮席卷全球的今天&#xff0c;AI CODING 已經不是企業研發團隊的可選項&#xff0c;而是必選項。如果你是企業…

windows下hashcat使用gpu破解execl打開密碼

需要的軟件 1.hashcat &#xff1a;https://hashcat.net 2.john the ripper &#xff1a;https://www.openwall.com 獲取execl加密文件的Hash PS G:\dl\john-1.9.0-jumbo-1-win64\john-1.9.0-jumbo-1-win64\run> python .\office2john.py .\test6.xlsx test6.xlsx:$office$*…

SpringCloud -- Nacos詳細介紹

5. Nacos 5.1 Nacos介紹 Nacos 可以理解為微服務的“電話簿 遙控器”。它是阿里巴巴開源的一個核心工具&#xff0c;主要解決微服務架構中的兩大問題&#xff1a; 5.1.1 服務注冊與發現&#xff08;電話簿&#xff09; 服務注冊&#xff1a;當某個微服務&#xff08;比如“訂單…

【狂熱算法篇】探尋圖論幽徑之SPFA算法:圖論迷宮里的閃電尋徑者(通俗易懂版)

?????本篇帶大家探究的是SPFA算法&#xff1b;從基本理解&#xff0c;畫圖分析展示&#xff0c;再到最后的代碼實現&#xff0c;以及為何要這樣實現代碼&#xff0c;等一些細節問題做解釋&#xff0c;相關題型應用&#xff0c;非常值得喲&#xff0c;尤其是剛入門的小白學…

webrtc網頁一對一通話

基于flutter-webrtc-server做的更改&#xff0c;只使用網頁實現語音和視頻一對一通話&#xff0c;不支持多對多。 項目地址: https://github.com/chging/rtc-server

Java調用bat執行python腳本

1、問題概述&#xff1f;在windows環境中可以通過Java調用bat執行文件&#xff0c;從而調用python腳本&#xff0c;使用起來方便。2、實現方式&#xff1f;2.1、核心代碼bat文件可以在任意位置//獲取文件在項目中的文職 String batFilePathSystem.getProperty("user.dir&q…

JavaWeb 歡迎頁設置詳解

JavaWeb 歡迎頁設置詳解 歡迎頁&#xff08;Welcome Page&#xff09;是用戶訪問 Web 應用根目錄時自動展示的默認頁面。在 JavaWeb 中有多種配置方式&#xff1a;一、配置方式 1. 通過 web.xml 配置&#xff08;傳統方式&#xff09; <web-app><!-- 配置歡迎頁列表 -…