計數排序+桶排序+基數排序 詳講(思路+圖解+代碼詳解)

文章目錄

  • 計數排序+桶排序+基數排序
    • 一、計數排序
          • 概念:
          • 寫法一:
          • 寫法二:
    • 二、桶排序
        • 概念
        • 代碼
    • 三、基數排序
      • 概念
      • 1.LSD排序法(最低位優先法)
      • 2.MSD排序法(最高位優先法)
    • 基數排序VS基數排序VS桶排序


計數排序+桶排序+基數排序


一、計數排序

在這里插入圖片描述

  • 時間復雜度:
  • 空間復雜度:
  • 穩定性:穩定
概念:
  • 非基于比較的排序

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

    1.統計相同元素出現的個數

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

  • 計數排序使用的場景:給出指定范圍內的數據進行排序

  • 使用場景:一組集中在某個范圍內的數據

寫法一:
  • 通過遍歷計數數組,循環輸出計數數組存的次數

在這里插入圖片描述

  • 1.遍歷數組找到最小值最大值
  • 2.根據最大最小值,申請一個計數數組
  • 3.遍歷待排數組進行計數
  • 4.遍歷計數數組進行輸出
 /*** 計數排序*無法保證穩定* @param array*/public static void countSort2(int[] array) {//1.遍歷數組找到最大值和最小值int MAX = array[0];int MIN = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}if (array[i] < MIN) {MIN = array[i];}}//2.根據最大最小值,申請一個計數數組int len = MAX - MIN + 1;//長度int[] count = new int[len];//3. 遍歷待排數組進行計數for (int i = 0; i < array.length; i++) {count[array[i] - MIN]++;}//4.遍歷計數數組進行輸出int index = 0;//array數組新的下標for (int i = 0; i < count.length; i++) {while (count[i] > 0) {array[index] = i + MIN;//+最小值,求出真正的數count[i]--;index++;}}}
寫法二:
  • 寫定數組的大小,用臨時數組存儲結構
  • 計算每個元素在排序后的數組中的最終位置
  • 根據計數數組將元素放到臨時數組b中,實現排序
  • 從后往前,根據原來數組的內容,在計數數組中找到要填寫在b數組中的位置,
  • 計數數組記錄的不再是數字出現是次數,而是應該在數組中存放的位置下標

在這里插入圖片描述

 /*** 計數排序*穩定* @param array*/public static void countSort(int[] array) {int len = array.length;final int MAX = 256;//常量確定數組大小int[] c = new int[MAX];//計數數組int[] b = new int[MAX];//臨時數組,存放結果//統計每個元素的出現次,進行計數for (int i = 0; i < len; i++) {c[array[i]]++;// 將a[i]作為索引,對應計數數組c中的位置加1}// 計算每個元素在排序后的數組中的最終位置for (int i = 1; i < MAX; i++) {c[i] += c[i - 1];// 計數數組中每個元素的值等于它前面所有元素的值之和}// 根據計數數組將元素放到臨時數組b中,實現排序for (int i = len - 1; i >= 0; i--) {b[c[array[i]] - 1] = array[i];// 將a[i]放入臨時數組b中的正確位置c[array[i]]--;// 對應計數數組c中的位置減1,確保相同元素能夠放在正確的位置}// 將臨時數組b中的元素復制回原數組a,完成排序for (int i = 0; i < len; i++) {array[i] = b[i];}}

二、桶排序

概念

劃分多個范圍相同的區間,每個子區間自排序,最后合并

  • 桶排序是計數排序的擴展版本,計數排序:每個桶只存儲單一鍵值

  • 桶排序: 每個桶存儲一定范圍的數值,確定桶的個數和范圍

  • 將待排序數組中的元素映射到各個對應的桶中,對每個桶進行排序

  • 最后將非空桶中的元素逐個放入原序列中

在這里插入圖片描述

代碼
    public static void bucketSort(int[] array){// 計算最大值與最小值int max = Integer.MIN_VALUE;int min = Integer.MAX_VALUE;for(int i = 0; i < array.length; i++){max = Math.max(max, array[i]);min = Math.min(min, array[i]);}// 計算桶的數量int bucketNum = (max - min) / array.length + 1;ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);for(int i = 0; i < bucketNum; i++){bucketArr.add(new ArrayList<Integer>());}// 將每個元素放入桶for(int i = 0; i < array.length; i++){int num = (array[i] - min) / (array.length);bucketArr.get(num).add(array[i]);}// 對每個桶進行排序for(int i = 0; i < bucketArr.size(); i++){Collections.sort(bucketArr.get(i));}// 將桶中的元素賦值到原序列int index = 0;for(int i = 0; i < bucketArr.size(); i++){for(int j = 0; j < bucketArr.get(i).size(); j++){array[index++] = bucketArr.get(i).get(j);}}}

三、基數排序

概念

  • 基數排序是一種非比較型整數排序算法

  • 將整數按位數切割成不同的數字,然后按每個位數分別比較

  • 使用場景:按位分割進行排序,適用于大數據范圍排序,打破了計數排序的限制

  • 穩定性:穩定

  • 按位分割技巧:arr[i] / digit % 10,其中digit為10^n。

在這里插入圖片描述

1.LSD排序法(最低位優先法)

  • 從最低位向最高位依次按位進行計數排序。

  • 進出的次數和最大值的位數有關

  • 桶可以用隊列來表示

  • 數組的每個元素都是隊列

在這里插入圖片描述

  • 1.先遍歷找到最大值
  • 2.求出最高位

在這里插入圖片描述

    public static void radixSortR(int[] array) {//10進制數,有10個桶,每個桶最多存array.length個數int[][] bucket = new int[10][array.length];//桶里面要存的具體數值int[] bucketElementCounts = new int[10];//用來計算,統計每個桶所存的元素的個數,每個桶對應一個元素//1.求出最大數int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位數,先變成字符串,求字符串長度int MAXCount = (MAX + "").length();//最大位數的個數,進行幾次計數排序for (int i = 0; i < MAXCount; i++) {//i代表第幾次排序//放進桶中for (int k = 0; k < array.length; k++) {//k相當于遍歷待排數值//array[k] /(int) Math.pow(10, i)%10 求出每次要比較位的數//求的是個位,并且是對應趟數的個位int value = (array[k] / (int) Math.pow(10, i)) % 10;//根據求出的位數,找到對應桶,放到對應桶的位置bucket[value][bucketElementCounts[value]] = array[k];//不管value 為多少,bucketElementCounts[value]的值都為0//相當于存到對應桶的0位bucket[value][0]bucketElementCounts[value]++; //從0->1//對應桶的技術數組開始計數}//取出每個桶中的元素,賦值給數組int index = 0;//array新的下標for (int k = 0; k < bucketElementCounts.length; k++) {//遍歷每個桶if (bucketElementCounts[k] != 0) {//桶里有元素for (int j = 0; j < bucketElementCounts[k]; j++) {//比那里每個桶的元素array[index] = bucket[k][j];index++;}}bucketElementCounts[k] =0;//每個桶遍歷完后,清空每個桶的元素;}}}

2.MSD排序法(最高位優先法)

在這里插入圖片描述

  • 從最高位向最低位依次按位進行排序。
  • 按位遞歸分組收集
  • 1.查詢最大值,獲取最高位的基數
  • 2.按位分組,存入桶中
  • 3.組內元素數量>1,下一位遞歸分組
  • 4.組內元素數量=1.收集元素
   /*** 基數排序--MSD--遞歸* @param array*/public static void radixSortMSD(int[] array) {//1.求出最大數int MAX = array[0];for (int i = 1; i < array.length; i++) {if (array[i] > MAX) {MAX = array[i];}}//求最大值的位數,先變成字符串,求字符串長度int MAXCount = (MAX + "").length();// 計算最大值的基數int radix = new Double(Math.pow(10, MAXCount - 1)).intValue();int[] arr = msdSort(array, radix);System.out.println(Arrays.toString(arr));}public static int[] msdSort(int[] arr, int radix){// 遞歸分組到個位,退出if (radix <= 0) {return arr;}// 分組計數器int[] groupCounter = new int[10];// 分組桶int[][] groupBucket = new int[10][arr.length];for (int i = 0; i < arr.length; i++) {// 找分組桶位置int position = arr[i] / radix % 10;// 將元素存入分組groupBucket[position][groupCounter[position]] = arr[i];// 當前分組計數加1groupCounter[position]++;}int index = 0;int[] sortArr = new int[arr.length];// 遍歷分組計數器for (int i = 0; i < groupCounter.length; i++) {// 組內元素數量>1,遞歸分組if (groupCounter[i] > 1) {int[] copyArr = Arrays.copyOf(groupBucket[i], groupCounter[i]);// 遞歸分組int[] tmp = msdSort(copyArr, radix / 10);// 收集遞歸分組后的元素for (int j = 0; j < tmp.length; j++) {sortArr[index++] = tmp[j];}} else if (groupCounter[i] == 1) {// 收集組內元素數量=1的元素sortArr[index++] = groupBucket[i][0];}}return sortArr;}

基數排序VS基數排序VS桶排序

  • 都是非比較型排序

  • 三種排序算法都利用了桶的概念

    1.計數排序:每個桶只存儲單一鍵值;

    2.基數排序:根據鍵值的每位數字來分配桶

    3.桶排序: 每個桶存儲一定范圍的數值;

點擊移步博客主頁,歡迎光臨~

偷cyk的圖

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

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

相關文章

內容營銷頻頻出圈,這些品牌號做對了什么?

小紅書擁有大量的年輕用戶&#xff0c;通過運營品牌號既能降低投放成本&#xff0c;又能更好地連接消費者和品牌&#xff0c;在平臺完成一站式閉環營銷。 今天就借助幾個成功案例&#xff0c;來分析下他們是如何搭建官方賬號&#xff0c;通過內容運營吸引更多用戶&#xff0c;實…

一款專為POS機設計的芯片解決方案

一、基本概述 HCM8003設計用于磁條讀卡器系統。它會從F/2F恢復時鐘和數據信號磁產生的數據流頭HCM8003將用于數據速率從200到15000比特每秒。 二、典型電路 內部數據的采集和跟蹤這個范圍是自動的。可以應用于POS機終端設備、磁卡門禁系統、身份識別等場合。 三、引腳定義 四…

redis的主從復制,哨兵模式

1.主從復制 主從復制&#xff1a;主從復制是redis實現高可用的基礎&#xff0c;哨兵模式和集群都是在主從復制的基礎之上實現高可用 主從復制實現數據的多機備份&#xff0c;以及讀寫分離&#xff08;主服務器負責寫&#xff0c;從服務器只能讀&#xff09; 缺陷&#xff1a…

PyTorch基本操作和工作流程

1. PyTorch基礎 張量&#xff08;Tensors&#xff09;&#xff1a; 學習 PyTorch 中表示數據的基本單元。了解如何創建、操作和使用張量。 自動微分&#xff08;Autograd&#xff09;&#xff1a; 了解 PyTorch 的自動微分機制&#xff0c;這是訓練神經網絡的核心。 模型定義…

Android registerForActivityResults使用詳解以及實現原理

registerForActivityResult 使用用途是監聽Activity結果。 以下是使用樣例 //需要傳遞Request用于解析Intent和解析上個Activity返回的結果 val launchdata = registerForActivityResult<PickVisualMediaRequest, Uri?>(ActivityResultContracts.PickVisualMedia()) {…

中國人工智能系列白皮書 AIGC

https://www.caai.cn/index.php?s/home/article/detail/id/3188.html

【git】使用ssh

前言 git之前一直使用https&#xff0c;因為很方便隨時隨地都可以用。最近把代碼托管到GitHub&#xff0c;使用https就使用不了。后面聽同事說GitHub使用ssh是沒問題的&#xff0c;就想著嘗試一下。 git ssh配置 設置用戶名和郵箱 git config --global use.name username g…

OpenCV實現圖像噪聲、去噪基本方法

一、噪聲分類 1、高斯噪聲 指服從高斯分布&#xff08;正態分布&#xff09;的一類噪聲&#xff0c;其產生的主要原因是由于相機在拍攝時視場較暗且亮度不均勻造成的&#xff0c;同時相機長時間工作使得溫度過高也會引起高斯噪聲&#xff0c;另外電路元器件白身噪聲和互相影響…

acwing算法基礎之數學知識--求組合數基礎版

目錄 1 基礎知識2 模板3 工程化 1 基礎知識 &#xff08;一&#xff09; 組合數 C n k C_n^k Cnk?的計算公式&#xff0c; C n k n ? ( n ? 1 ) ? ( n ? k 1 ) 1 ? 2 ? k C_n^k\frac{n\cdot(n-1)\cdots(n-k1)}{1\cdot 2\cdots k} Cnk?1?2?kn?(n?1)?(n?k1)? …

laravel-admin導出excel全部,表中無id列導出失敗

laravel-admin導出excel時&#xff0c;導出全部數據&#xff0c;但是表中沒有id字段&#xff0c;然后就無法導出excel&#xff1b; 就直接顯示 一開始我也很著急&#xff0c;弄了半天還是不行&#xff0c;然后重寫還是有問題 最后發現底層代碼排序是按照id排序的orderBy(id, a…

Unity地面交互效果——6、地形動態頂點置換和曲面細分

回到目錄 Unity置換貼圖局部距離曲面細分 大家好&#xff0c;我是阿趙。 ??這篇文章是我無聊的時候做了一個demo&#xff0c;覺得挺有趣&#xff0c;于是就發上來。這里面包含了4個內容&#xff1a;置換貼圖、頂點偏移、局部曲面細分&#xff0c;曲面細分按距離調整強度。 …

JVS低代碼表單設計:數據聯動詳解(多級數據級、數據回顯等)

在這信息化時代&#xff0c;表單作為數據的收集和展示工具&#xff0c;已經滲透到不同的角落。JVS低代碼對表單的設計和操作進行了不斷的優化和創新。其中&#xff0c;聯動回顯作為一項重要的功能&#xff0c;無論是多級數據級聯控制、組件的聯動控制&#xff0c;還是多表的數據…

【0基礎學Java第三課】-- 運算符

3. 運算符 3.1 什么是運算符3.2 算術運算符3.2.1 **基本四則運算符&#xff1a;加減乘除模( - * / %&#xff09;**3.2.2 增量運算符 - * %3.2.3 自增/自減運算符 -- 3.3 關系運算符3.4邏輯運算符(重點)3.4.1 邏輯與 &&3.4.2 邏輯 ||3.4.3邏輯非 !3.4.4 短路求值 3.5 …

DBS note4:Buffer Management

目錄 1、介紹 2、緩沖池 3、處理頁面請求 4、LRU替換和時鐘策略 1&#xff09;順序掃描性能 - LRU 5、最近最常使用替換策略&#xff08;MRU Replacement&#xff09; 1&#xff09;Sequential Scanning Performance - MRU 6、練習題 1&#xff09;判斷真假 2&#xf…

華清遠見嵌入式學習——網絡編程——作業4

作業要求&#xff1a;①使用IO多路復用中的select函數實現TCP并發服務器客戶端 ②使用IO多路復用中的poll函數實現TCP并發服務器的服務器端 一、 代碼 #include <myhead.h>#define SERPORT 8888 //服務器端口號 #define SERIP "192.168.114.113"…

Samsung下origen中uboot的配置與編譯

uboot的特點&#xff1a; n代碼結構清晰 n 支持豐富的處理器與開發板&#xff0c;易于移植 n 支持豐富的用戶命令 n 支持豐富的網絡協議 n 支持豐富的文件系統 n 支持豐富的設備驅動 n 更新活躍、用戶較多、資料豐富 n 開放源代碼 n 較高的穩定性 n 不具有通用性&#xff08;不…

JavaScript編程基礎 – 布爾值(Booleans)

JavaScript編程基礎 – 布爾值(Booleans) Javascript Programming Essentials – Booleans 一個JavaScript布爾值包含兩個值中的一個&#xff0c;即 true 或者 false。 本文簡要介紹JavaScript布爾值的具體應用&#xff0c;以及可能作為對象的布爾值等。 1. 布爾值(Booleans)…

Go語言超全詳解(入門級)

文章目錄 1. Go語言的出現2. go版本的hello world3. 數據類型3.0 定義變量3.0.1 如果變量沒有初始化3.0.2 如果變量沒有指定類型3.0.3 :符號3.0.4 多變量聲明3.0.5 匿名變量3.0.6 變量作用域 3.1 基本類型3.2 指針3.2.1 指針聲明和初始化3.2.2 空指針 3.3 數組3.3.1 聲明數組3.…

java+mysql的校園兼職微信小程序(附源碼 調試 文檔)

校園兼職微信小程序 摘要一、引言二、國內外研究現狀三、系統設計四、系統實現與界面展示五、源碼獲取 摘要 本文詳述了一個基于Java和MySQL數據庫技術的校園兼職微信小程序的畢業設計。系統主要分為三種用戶角色&#xff1a;管理員、學生用戶和商家用戶。管理員擁有學生管理、…