排序的簡單理解(上)

1. 排序的概念及引用

1.1 排序的概念

????????排序:所謂排序,就是使一串記錄,按照其中的某個或某些關鍵字的大小,遞增或遞減的排列起來的操作(按照我們的需求能夠有序的將數據信息排列起來)。

????????穩定性:假定在待排序的記錄序列中,存在多個具有相同的關鍵字的記錄,若經過排序,這些記錄的相對次序保持 不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,則稱這種排序算法是穩 定的;否則稱為不穩定的(如果一份數據中有多個相同的數據,在經過排序后這幾個數據的先后邏輯順序沒有發生改變就稱為該算法穩定性強)。

????????

????????內部排序:數據元素全部放在內存中的排序。

????????外部排序:數據元素太多不能同時放在內存中,根據排序過程的要求不能在內外存之間移動數據的排序。

1.2?常見的排序算法

? ? ? ? 我們本次學習主要學習一下四類七種排序算法;

? ? ? ? 下文我們將詳細的介紹不同的排序算法及實現?

2. 插入排序

2.1 直接插入排序

???????? 直接插入排序是一種簡單的插入排序法,其基本思想是: 把待排序的記錄按其關鍵碼值的大小逐個插入到一個已經排好序的有序序列中直到所有的記錄插入完為止,得到一個新的有序序列 。實際中我們玩撲克牌時,就用了插入排序的思想

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

2.1.1 詳細思路與圖解分析

????????把n個待排序的元素看成為一個有序表和一個無序表,開始時有序表中只包含一個元素(默認),無序表中包含n-1個元素,排序過程中每次從無序表中取出第一個元素,把它的排序碼依次與有序表元素的排序碼從后往前一一進行比較,將它插入到有序表中的適當位置,使之成為一個新的有序表。

????????以序列:{55, 85, 21, 12, 5}?為例,?圖解如下:

? ? ? ??

????????紅色部分為每輪認定的有序部分,其余顏色為認定的無序部分。綠色標識為每輪遍歷的無序序列的位置,將該位置的元素逐一與有序部分進行比較,找到合適的位置進行順序表的插入操作。?

? ? ? ? 代碼一:

 public static void insertSort(int[] array){//判斷數組為空,無法排序if (array.length <1){return;}for (int i = 1; i < array.length; i++) {//定義待插入位置和待插入的數值int insertIndex = i-1;//arr[i]前面的位置,便于插入int insertValue = array[i];//現將待插入的數值保存到變量中//給insertValue找到待插入的位置//1.insertIndex > 0防止越界//2.insertValue < arr[insertIndex] 說明還未找到待插入的位置,// 還要繼續與前面的那個位置進行比較,直到insertValue > arr[insertIndex]//說明找到了要插入的點的索引while (insertIndex >= 0 && insertValue < array[insertIndex]){array[insertIndex+1] = array[insertIndex];insertIndex--;}if (insertIndex != i){//要插入的位置insertindex與剛開始的該元素存放的位置不一樣//我們比insertindex位置大,所以要插到他后面,所以加一array[insertIndex+1] = insertValue; //插入}System.out.println("第" + i + "輪: " + Arrays.toString(array));}}

? ? ? ? 測試代碼如下:

public static void main(String[] args) {int[] array = {55, 85, 21, 12, 5};System.out.println("排序前: " + Arrays.toString(array));insertSort(array);System.out.println("排序后: " + Arrays.toString(array));}

? ? ? ? ?實現效果如下:

? ? ? ? ??

? ? ? ? 代碼二展示(簡單易理解):

 public static void instersort(int[] arr){for (int i = 1; i <arr.length ; i++) {int tmp=arr[i];int j = i-1;for (; j>=0 ; j--) {if(arr[j]>tmp){arr[j+1]=arr[j];}else{break;}}arr[j+1]=tmp;}}

? ? ? ? 結果展示:

? ? ? ? ??

2.2.2 分析與總結

/*** 時間復雜度:*    最壞情況下:O(n^2)  5   4   3   2   1*    最好情況下:O(n)   當前數據越有序,排序越快   1  2  3  4  5*    適用于:待排序序列  已經基本上趨于有序了!* 空間復雜度: O(1)* 穩定性:穩定的*/

以下是動圖展示:

2.2?希爾排序( 縮小增量排序 )

2.2.1 詳細思路與圖解分析

????????希爾排序法又稱縮小增量法

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

  • 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率;
  • 但插入排序一般來說是低效的,因為插入排序每次只能將數據移動一位;

????????希爾排序法的基本思想是:把記錄按下標的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至 1 時,整個文件恰被分成一組,算法便終止。希爾排序是非穩定排序算法。

????????以序列:?{8, 9, 1, 7, 2, 3, 5, 6, 4, 0}?為例

1、初始步長gap = length/2 = 5,意味著將整個數組分為了5組,即[8,3],[9,5],[1,6],[7,4],[2,0],對每組進行插入排序,得到序列:{3,5,1,4,0,8,9,6,7,2},可以看到:3,5,4,0這些小元素都被提到前面了

2、縮小增量gap = 5/2 = 2,數組被分為兩組,即[3,1,0,9,7],[5,4,8,6,2],對這兩組分別進行直接插入排序,可以看到,整個數組的有序程度更進一步了

3、再次縮小增量,gap = 2/2 = 1,此時整個數組為[0,2,1,4,3,5,7,6,9,8],進行一次插入排序,即可實現數組的有序化(僅需要簡單微調,而無需大量移動操作)

? ? ? ? 代碼一實現如下:

public static void shellSort(int[] arr){//設定步長for (int gap = arr.length / 2; gap > 0; gap /= 2){//將數據分為arr.length/gap組,逐個對其所在的組進行插入排序//按照分組一直進行下面的每組直接插入,直到整個元素集合分為一組for (int i = gap; i < arr.length; i++) {//遍歷各組中的所有元素,步長為gapint j = i;//每一組的元素個數定義為jint temp = arr[j]; //記錄待插入的值while (j - gap >= 0 && temp < arr[j-gap]){//移動arr[j] = arr[j-gap];j -= gap;}//找到位置,進行插入arr[j] = temp;}System.out.println(Arrays.toString(arr));}}

? ? ? ? 代碼二(較易理解):

    public void straightInsertion(int[] array,int gap) {int len = array.length;for(int i = gap; i < len ; i++) {int count = array[i];int j = i - gap;for( ; j >= 0; j-=gap) {if(count < array[j]) {array[j + gap] = array[j];} else {break;}}array[j + gap] = count;}}public void shellSort(int[] arrary) {int gap = arrary.length;while(gap  > 0) {gap = gap /2;straightInsertion(arrary,gap);}}

??????????測試代碼及結果如下:

 public static void main(String[] args) {int[] arr = {8, 9, 1, 7, 2, 3, 5, 6, 4, 0};System.out.println("排序前: " + Arrays.toString(arr));shellSort(arr);System.out.println("排序后: " + Arrays.toString(arr));}

?????????

2.2.2 分析與總結

1. 希爾排序是對直接插入排序的優化。
2. 當 gap > 1 時都是預排序,目的是讓數組更接近于有序。當 gap == 1 時,數組已經接近有序的了,這樣就會很快。這樣整體而言,可以達到優化的效果。我們實現后可以進行性能測試的對比。
3. 希爾排序的時間復雜度不好計算,因為 gap 的取值方法很多,導致很難去計算,因此在好些書中給出的希爾排序的時間復雜度都不固定。(時間復雜度不固定)
4. 穩定性:不穩定

3 選擇排序

????????基本思想:第一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后再從剩余的未排序元素中尋找到最小(大)元素,然后放到已排序的序列的末尾。以此類推,直到全部待排序的數據元素的個數為零。選擇排序是不穩定的排序方法。

3.1 直接選擇排序

? ? ? ? 動態圖解如下圖所示:

3.1.1?詳細思路與圖解分析

第一次:從arr[0]~arr[n-1]中選取最小值,與arr[0]進行交換;
第二次:從arr[1]~arr[n-1]中選取最小值,與arr[1]進行交換;
第三次:從arr[2]~arr[n-1]中選取最小值,與arr[2]進行交換;

第 i 次:從arr[i]~arr[i-1]中選取最小值,與arr[i]進行交換;
總共通過n-1次,可以得到從小到大的有序序列。

以序列:{8, 3, 2, 1, 7, 4, 6, 5} 為例!分步驟圖解如下:? ? ? ? ? ? ??

綜上所述:

  1. 在每趟排序時,都默認當前位置的元素為最小值,如果在遍歷過程中發現有比當前位置元素還小的值,則替換最小值。(先將最小值記錄,此趟遍歷完成再替換)
  2. 選擇排序一共有arr.length-1次趟排序。

? ? ? ? 代碼一如下實現:

  public static void selectSort(int[] arr){//選擇排序過程for (int i = 0; i < arr.length - 1; i++) {int minIndex = i; //假定最小索引,最小值為第一個元素int min = arr[minIndex];for (int j = i + 1; j < arr.length; j++) {if (min > arr[j]){//更新最小值min = arr[j];minIndex = j;}}//將最小值放進arr[i]if (i != minIndex){arr[minIndex] = arr[i];arr[i] = min;}//輸出每輪排序后的結果System.out.println("第" + (i+1) + "趟: " + Arrays.toString(arr));}}

? ? ? ? 代碼二(更易理解):

    public static void selectSort(int[] array) {for (int i = 0; i < array.length; i++) {int minIndex = i;int j = i+1;for (; j < array.length; j++) {if(array[j] < array[minIndex]) {minIndex = j;}}swap(array,i,minIndex);}}private static void swap(int[] array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}

? ? ? ? 測試代碼及結果:

public static void main(String[] args) {int[] array = {8, 3, 2, 1, 7, 4, 6, 5};System.out.println("排序前: " + Arrays.toString(array));selectSort(array);System.out.println("排序后: " + Arrays.toString(array));}

? ? ? ?

3.1.2 直接選擇排序的特性總結

  1. 直接選擇排序思考非常好理解,但是效率不是很好。實際中很少使用

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

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

  4. 穩定性:不穩定

3.2 堆排序

????????堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似完全二叉樹的結構,并同時滿足堆積的性質:即子結點的鍵值或索引總是小于(或者大于)它的父節點。堆排序可以說是一種利用堆的概念來排序的選擇排序。(關于堆的相關詳細知識見于前面相應章節)分為兩種方法:????????

????????大頂堆:每個節點的值都大于或等于其子節點的值,在堆排序算法中用于升序排列;

????????小頂堆:每個節點的值都小于或等于其子節點的值,在堆排序算法中用于降序排列;

3.2.1?詳細思路與圖解分析

????????圖解如下圖所示:?

由上圖所示,該方法思路如下所示:

  1. 創建一個堆 H[0……n-1];

  2. 把堆首(最大值)和堆尾互換;

  3. 把堆的尺寸縮小 1,并調用相應方法,目的是把新的數組頂端數據調整到相應位置;

  4. 重復步驟 2,直到堆的尺寸為 1

代碼實現如下:

    private  void swap(int[] array,int i,int j) {int tmp = array[i];array[i] = array[j];array[j] = tmp;}public  void heapSort(int[] array) {createBigHeap(array);int end = array.length-1;while (end > 0) {swap(array,0,end);shiftDown(array,0,end);end--;}}private  void createBigHeap(int[] array) {for (int parent = (array.length-1-1)/2; parent >= 0 ; parent--) {shiftDown(array,parent,array.length);}}private  void shiftDown(int[] array,int parent,int len) {int child = 2*parent+1;while (child < len) {if(child+1 < len && array[child] < array[child+1]) {child++;}if(array[child] > array[parent]) {swap(array,child,parent);parent = child;child = 2*parent+1;}else {break;}}}

3.2.2 分析與總結

  1. 堆排序使用堆來選數,效率就高了很多。

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

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

  4. 穩定性:不穩定

ps:本次的學習就到這里了,如果喜歡的話就請一鍵三連哦~~~?

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

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

相關文章

TeeChart.NET 2023.11.17 Crack

.NET 的 TeeChart 圖表控件提供了一個出色的通用組件套件&#xff0c;可滿足無數的圖表需求&#xff0c;也針對重要的垂直領域&#xff0c;例如金融、科學和統計領域。 數據可視化 數十種完全可定制的交互式圖表類型、地圖和儀表指示器&#xff0c;以及完整的功能集&#xff0c…

醫療設備智慧管理助力醫院提質增效,阿基米德amp;健康界實踐分享

近日&#xff0c;蘇州阿基米德網絡科技有限公司與醫療領域頭部級媒體健康界&#xff0c;聯合舉辦“數智為擎 提質增效——醫學裝備智慧管理創新發展論壇”的直播活動。 直播現場&#xff0c;來自上海交通大學醫學院附屬同仁醫院、中華醫學會航海醫學分會、蘇州阿基米德的專家們…

統信UOS_麒麟KYLINOS上使用命令行配置NTP服務器

原文鏈接&#xff1a;統信UOS/麒麟KYLINOS上使用命令行配置NTP hello&#xff0c;大家好啊&#xff0c;今天我要給大家介紹的是在統信UOS/麒麟KYLINOS操作系統上使用命令行配置NTP&#xff08;Network Time Protocol&#xff09;服務器的方法。在內網環境下&#xff0c;許多企業…

13、C++異常處理

13、c異常處理 拋出異常捕獲異常未拋出異常時的流程拋出異常時的流程捕獲異常匹配順序異常說明異常處理構造函數中的異常析構函數中的異常標準庫異常類 拋出異常 throw 異常對象可以拋出基本類型的對象&#xff0c;如:throw -1;throw "內存分配失敗!";也可以拋出類類…

AVP對縱向控制ESP(Ibooster)的需求規范

目錄 1. 版本記錄... 3 2. 文檔范圍和控制... 4 2.1 目的/范圍... 4 2.2 文檔沖突... 4 2.3 文檔授權... 4 2.4 文檔更改控制... 4 3. 功能概述... 5 4. 系統架構... 6 5. 主要安全目標... 7 5.1 …

FreeSSL申請免費域名證書

本文詳細講解如何申請免費證書&#xff0c;需要先準備好域名&#xff0c;將服務器IP和域名綁定。 1、注冊FreeSSL賬號 網址&#xff1a; https://freessl.org/ 2、申請流程 登錄后首頁輸入域名&#xff0c;然后點擊Create certificate&#xff0c;跳轉到證書申請頁面。 或者…

Pytorch深度強化學習1-6:詳解時序差分強化學習(SARSA、Q-Learning算法)

目錄 0 專欄介紹1 時序差分強化學習2 策略評估原理3 策略改進原理3.1 SARSA算法3.2 Q-Learning算法 0 專欄介紹 本專欄重點介紹強化學習技術的數學原理&#xff0c;并且采用Pytorch框架對常見的強化學習算法、案例進行實現&#xff0c;幫助讀者理解并快速上手開發。同時&#…

老人的數目

給你一個下標從 0 開始的字符串 details 。details 中每個元素都是一位乘客的信息&#xff0c;信息用長度為 15 的字符串表示&#xff0c;表示方式如下&#xff1a; 前十個字符是乘客的手機號碼。接下來的一個字符是乘客的性別。接下來兩個字符是乘客的年齡。最后兩個字符是乘…

QGIS 加載在線XYZ地圖圖層

QGIS 加載在線XYZ地圖圖層 定義并添加必應XYZ圖層 Go to Layer > Add Layer > Add XYZ Layer…Click NewName as BingMaps(as you wish)URL as http://ecn.t3.tiles.virtualearth.net/tiles/a{q}.jpeg?g1click OkSelect XYZ Connections as Bing Maps(Which you creat…

PR自動剪輯視頻工具AI智能剪輯插件AutoPod

推薦一款可以提高剪輯效率&#xff0c;節約時間成本的AI人工智能自動剪輯視頻制作工具pr插件Autopod&#xff0c;輔助你更快地完成視頻內容的編輯工作。 Autopod 插件是一款應用于 Adobe Premiere Pro 軟件的插件&#xff0c;用于自動剪輯。該插件能夠識別和處理視頻和音頻素材…

Spring Boot 常用注解分類

目錄 1.核心注解&#xff1a;2.配置相關注解&#xff1a;3.控制器相關注解&#xff1a;4.數據訪問相關注解&#xff1a;5.測試相關注解&#xff1a;6.條件注解&#xff1a;7.AOP相關注解&#xff1a;8.定時任務相關注解&#xff1a;9.消息隊列相關注解&#xff1a;10.Spring Se…

函數式編程解析:定義、功能與Java實踐

目錄 一、函數式編程1.1 什么是函數式編程1.2 函數式編程特征1.2.1 純函數1.2.2 函數是一等公民 1.3 函數式編程在java中的實踐 參考資料 一、函數式編程 1.1 什么是函數式編程 函數式編程&#xff08;Functional Programming&#xff09;是一種編程范式&#xff0c;它將計算…

ES6中的迭代器和set、map集合

什么是迭代器&#xff1f; 一種機制&#xff0c;也是一種接口&#xff0c;為數據結構提供統一訪問接口&#xff0c;依次處理數據據結構成員 只要實現了迭代器接口&#xff0c;就可以使用for...of循環遍歷。 /*** 迭代器是一種機制 是一種接口 只要數據解構實現了接口 就可…

力扣labuladong一刷day36天

力扣labuladong一刷day36天 一、96. 不同的二叉搜索樹 題目鏈接&#xff1a;https://leetcode.cn/problems/unique-binary-search-trees/ 思路&#xff1a;這是一道典型的動態規劃題&#xff0c;從n3來看 子樹有幾種形態 (0, 2)、(1, 1)、(2, 0)有規律可循&#xff0c;即為左…

飛天使-linux操作的一些技巧與知識點4

文章目錄 ansible配置文件的優先級嘗試開始進行操作ansible常用模塊ansible 的playbook示例安裝phpplaybook中變量的引用 ansible yum install -y ansible 測試是否可用 ansible localhost -m ping /etc/ansible/ansible.cfg &#xff1a;主配置文件&#xff0c;配置 ansible…

大公司求我用Kotlin寫個通用爬蟲模板

bug虐我千百遍&#xff0c;我待他如初戀。每次深夜挑燈都是我與bug較量的時間。今天我要說的就是寫一個爬蟲模版&#xff0c;自動抓取百度圖片的教程&#xff0c;這次使用Kotlin編寫的爬蟲程序在Scrapy框架下完成的&#xff0c;如有不足歡迎指正。 首先&#xff0c;使用Kotlin編…

Mybatis-Plus源碼解析之@MapperScan(一)

group : com.baomidou version:3.5.2.2-SNAPSHOT baomidou官網可以從快速開始了解到&#xff0c;除了配置數據源&#xff0c;最重要的就是MapperScan 注解&#xff0c;在 Spring Boot 啟動類中添加 MapperScan 注解&#xff0c;掃描 Mapper 文件夾。 MapperScan 按照慣例&…

angular form 組件、雙向綁定;反應式表單

1.使用雙向綁定&#xff0c;以及angular的表單提交功能 app.moudle中引入 雙向綁定 [(ngModel)]"text" ??????? 效果 提交表單 2.反應式表單 在app.module.ts中引入在組件中引入&#xff0c;并放在一個變量里 在初始化時實列化這個module 定義規則 在html…

Linux:環境變量

目錄 1.基本變量 2.通過代碼獲取環境變量 2.1 main傳參 2.2 全局變量environ 2.3 系統調用getenv() 3.在腳本文件中添加環境變量 4.環境變量通常是具有全局屬性 1.基本變量 環境變量(environment variables)一般是指在操作系統中用來指定操作系統運行環境的一些參數…

商用中央空調市場分析:預計2028年將達到628億元

商用空調一直以來都沒有一個相對比較明確的概念&#xff0c;一直以來被認為是制冷空調市場的一個細分子行業。現在比較一致的觀點是&#xff0c;可以納入商用空調范疇的產品可以包括戶式中央空調產品、部分傳統中央空調產品以及部分家用空調。商用空調已普遍采用直流變頻領先技…