C++ 數據結構算法 學習筆記(32) -五大排序算法

C++ 數據結構算法 學習筆記(32) -五大排序算法

選擇算法

如下若有多個女生的身高需要做排序:

在這里插入圖片描述

常規思維:

  1. 第一步先找出所有候選美女中身高最高的,與最后一個數交換

在這里插入圖片描述

  1. 第二步再找出除最后一位美女外其它美女中的最高者,與倒數第二個美女交換位置

在這里插入圖片描述

  1. 再找出除最后兩位美女外其它美女中的最高者,與倒數第三個美女交換位置,因為倒數 第三個本身已是最大的,所以實際無需交換.

在這里插入圖片描述

  1. 重復以上步驟,直到最后只剩下一人,此時,所有的美女均已按照身高由矮到高的 順序排列

在這里插入圖片描述

代碼實現:

#include<stdio.h>
#include<stdlib.h>
void swap(int* num1, int* num2)//交換兩個變量的值
{int temp = *num1;*num1 = *num2;*num2 = temp;
}void SelectSort1(int arr[], int len) {for (int i = 0; i < len - 1; i++) {int max = 0;for (int j = 1; j < len - i; j++) { //查找未排序的元素if (arr[j] > arr[max]) { //找到目前最小值max = j;}}//printf("max:%dbeauties%d\n",max,len-i-1);if (max != (len - i - 1)) {swap(&arr[max], &arr[len - i - 1]);}}
}
void SelectSort2(int arr[], int len) {int i, j;for (i = 0; i < len - 1; i++){int min = i;for (j = i + 1; j < len; j++) { //查找未排序的元素if (arr[j] < arr[min]) { //找到目前最小值min = j; //記錄最小值}}swap(&arr[min], &arr[i]); //交換}
}
int main(void) {int beauties[] = { 163,161,158,165,171,170,163,159,162 };int len = sizeof(beauties) / sizeof(beauties[0]);SelectSort2(beauties, len);for (int i = 0; i < len; i++) {printf("%d ", beauties[i]);}system("pause");
}

冒泡算法

當我們采用前面的選擇排序時,我們仍然要將候選者遍歷5遍,才能完成最終的排序,但其 實,本身這些美女出了第一個外,已經很有序了,我們只需要把第一個和第二個交換,然后又和 第三個交換,如此循環,直到和最后一個交換后,整個數組基本就有序了!

在這里插入圖片描述

當然,并不是每次都這么幸運,像下面的情況就會更復雜一些,一趟并不能完全解決問題, 我們需要多趟才能解決問題.

在這里插入圖片描述

經過上述五步后,得到的結果:

在這里插入圖片描述

此時,我們只保障了最后一個數是最大的,并不能保障前面的數一定會有序,所以,我們繼續按 照上面五步對剩下的5個數繼續進行一次排序,數組就變得有序了. 以上過程就是冒泡排序:通過重復地遍歷未排序的數列,一次比較兩個元素,如果它們的順 序錯誤就把它們交換過來。走訪數列的工作是重復地進行直到沒有再需要交換,也就是說該數列 已經排序完成。這個算法的名字由來是因為越小的元素會經由交換慢慢得像泡泡一樣“”到數 列的頂端,故而得名

代碼實現:

#include <iostream>
#include <string>using namespace std;void swap(int* tmp1, int* tmp2)
{int tmp3 = *tmp1;*tmp1 = *tmp2;*tmp2 = tmp3;
}int main()
{int height2[] = { 156,162,161,172,167,169,155 };int height[] = { 155,158,161,163,172,174 };int size = sizeof(height) / sizeof(height[0]);for (int i = 0; i < size-1; i++){bool sorted = true;for (int j = 0; j < size-i-1; j++){if (height[j] > height[j+1]){	sorted = false;swap(&height[j], &height[j + 1]);}}if (sorted == true)	break;}for (int i = 0; i < size; i++){cout << height[i] << " ";}system("pause");return 0;
}

插入排序

在這里插入圖片描述

  1. 首先,我們只考慮第一個元素,從第一個元素171開始,該元素可以認為已經被排序;

在這里插入圖片描述

  1. 取下一個元素161并記錄,并讓161所在位置空出來,在已經排序的元素序列中從后向前掃 描;

    在這里插入圖片描述

  2. 該元素(171)大于新元素,將該元素移到下一位置;

    在這里插入圖片描述

  3. 171前已經沒有最大的元素了,則將161插入到空出的位置

    在這里插入圖片描述

  4. 取下一個元素163,并讓163所在位置空出來,在已經排序的元素序列中從后向前掃描;

    在這里插入圖片描述

  5. 該元素(171)大于新元素163,將該元素移到下一位置

    在這里插入圖片描述

  6. 繼續取171前的元素新元素比較,直到找到已排序的元素小于或者等于新元素的位置;新 元素大于161,則直接插入空位中

    在這里插入圖片描述

  7. 重復步驟2~7,直到完成排序

    在這里插入圖片描述

插入排序:它的工作原理是通過構建有序序列,對于未排序數據,在已排序序列中從后向前掃描, 找到相應位置并插入。插入排序在實現上,通常采用in-place排序(即只需用到O(1)的額外空間 的排序),因而在從后向前掃描過程中,需要反復把已排序元素逐步向后挪位,為最新元素提供 插入空間。

具體算法描述如下:

  1. 從第一個元素開始,該元素可以認為已經被排序;

  2. 取出下一個元素,在已經排序的元素序列中從后向前掃描;

  3. 如果該元素(已排序)大于新元素,將該元素移到下一位置; 重復步驟3,直到找到已排序的元素小于或者等于新元素的位置;

  4. 將新元素插入到該位置; 重復步驟2~5

代碼實現::

#include <iostream>
#include <string>using namespace std;void InsertSort(int* height, int size) 
{int current = 0;int preIndex = 0;for (int i = 1; i < size; i++){current = height[i];preIndex = i-1;while (preIndex >= 0 && height[preIndex] > current){height[preIndex + 1] = height[preIndex];preIndex--;}height[preIndex + 1] = current;}
}int main()
{int height[] = { 152,163,161,159,172,170,168,151 };int size = (sizeof(height) / sizeof(height[0]));InsertSort(height, size);cout << "The sorting result is" << endl;for (int i = 0; i < size; i++){cout << height[i] << " ";}system("pause");return 0;
}

希爾排序

插入排序雖好,但是某些特殊情況也有很多缺點,比如像下面這種情況

在這里插入圖片描述

169前的元素基本不用插入操作就已經有序,元素1和2的排序幾乎要移動數組前面的所有 元素!!!于是,有個老帥哥就提出了優化此問題的希爾排序!

希爾排序是希爾(Donald Shell)于1959年提出的一種排序算法。希爾排序也是一種插入排 序,它是簡單插入排序經過改進之后的一個更高效的版本,也稱為縮小增量排序。它與插入排序 的不同之處在于,它會優先比較距離較遠的元素。

希爾排序是把記錄按下表的一定增量分組,對每組使用直接插入排序算法排序;隨著增量逐 漸減少,每組包含的元素越來越多,當增量減至1時,所有元素被分成一組,實際上等同于執行一 次上面講過的插入排序,算法便終止。

希爾排序的基本步驟:

選擇增量:gap=length/2,縮小增量:gap=gap/2

增量序列:用序列表示增量選擇,{n/2,(n/2)/2,…,1}

先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,具體算法描述:

選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;

按增量序列個數k,對序列進行k趟排序;

每趟排序,根據對應的增量ti,將待排序列分割成若干長度為m的子序列,分別對各子表進 行直接插入排序;

僅增量因子為1時,整個序列作為一個表來處理,表長度即為整個序列的長度。

在這里插入圖片描述

#include <iostream>
#include <string>
using namespace std;void InsertSort(int arr[], int len)
{int gap = len / 2;for (; gap > 0; gap = gap / 2) {for (int i = gap; i < len; i++) {int current = arr[i];int j = 0;for (j = i - gap; j >= 0 && arr[j] > current; j -= gap) {arr[j + gap] = arr[j];}arr[j + gap] = current;}}
}int main()
{int height[] = { 152,163,161,159,172,170,168,151 };int size = (sizeof(height) / sizeof(height[0]));InsertSort(height, size);cout << "The sorting result is" << endl;for (int i = 0; i < size; i++){cout << height[i] << " ";}system("pause");return 0;
}

歸并排序

當兩個組數據已經有序,我們可以通過如下方式(以下簡稱歸并大法)讓兩組數據快速有序

在這里插入圖片描述

我們可以依次從兩組中取最前面的那個最小元素依次有序放到新的數組中,然后再把新數組 中有序的數據拷貝到原數組中,快速完成排序
在這里插入圖片描述

具體步驟:

對于下面這一組待排序的數組

在這里插入圖片描述

先以中間為界,把其均分為A和B兩個數組(如果是奇數個,允許兩組數相差一個)

在這里插入圖片描述

如果A和B兩組數據能夠有序,則我們可以通過上面的方式讓數組快速排好序。 此時,A組有4個成員,B組有5個成員,但兩個數組都無序,然后我們可以采用分治法繼 續對A組和B組進行均分,以A組為例,又可以均分A1和A2兩個組如下:

在這里插入圖片描述

均分后,A1組和A2組仍然無序,繼續利用分治法細分,以A1組為例,A1又可分成如下 兩組

在這里插入圖片描述

數組細分到一個元素后,這時候,我們就可以采用歸并法借助一個臨時數組將數組A1有序化! A2同理!

在這里插入圖片描述

依次類推,將A1組和A2組歸并成有序的A組,B組同理!

在這里插入圖片描述

最后,將A和B組使用歸并大法合并,就得到了完整的有序的結果!

在這里插入圖片描述

代碼實現:

#include <iostream>
#include <string>using namespace std;//void mergeAdd_demo(int arr[], int left, int mid, int right)
//{
//	int temp[64] = { 0 };
//	int i = left;
//	int j = mid;
//	int k = 0;
//
//	while (i < mid && j <= right)
//	{
//		if (arr[i] < arr[j])
//		{
//			temp[k++] = arr[i++];
//		}
//		else
//		{
//			temp[k++] = arr[j++];
//		}
//	}
//	while (i < mid)
//	{
//		temp[k++] = arr[i++];
//	}
//
//	while (j <= right)
//	{
//		temp[k++] = arr[j++];
//	}
//
//	memcpy(arr + left, temp, sizeof(int) * (right - left + 1));
//}void mergeAdd(int arr[], int left, int mid, int right, int* temp)
{//int temp[64] = { 0 };int i = left;int j = mid;int k = left;while (i < mid && j <= right){if (arr[i] < arr[j]){temp[k++] = arr[i++];}else{temp[k++] = arr[j++];}}while (i < mid){temp[k++] = arr[i++];}while (j <= right){temp[k++] = arr[j++];}memcpy(arr + left, temp + left, sizeof(int) * (right - left + 1));
}void mergeSort(int arr[], int left, int right, int* temp)
{int mid = 0;if (left < right){mid = left+(right-left)/2;mergeSort(arr, left, mid, temp);mergeSort(arr, mid + 1, right, temp);mergeAdd(arr, left, mid+1, right, temp);}
}int main()
{int height[] = { 10,11,12,13,2,4,5,8 };int len = sizeof(height) / sizeof(height[0]);int* temp = new int[len];//int mid = len / 2;mergeSort(height, 0, len - 1, temp);//mergeAdd(height, 0, mid, len - 1,temp);for (int i = 0; i < len; i++){cout << height[i] << " ";}system("pause");return 0;
}

快速排序

具體做法為:

  1. 每次選取第一個數為基準數;
  2. 然后使用“乾坤挪移大法”將大于和小于基準的元素分別放置于基準數兩邊;
  3. 繼續分別對基準數兩側未排序的數據使用分治法進行細分處理,直至整個序列有序。

對于下面待排序的數組:

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

代碼實現:

#include <iostream>
#include <string>using namespace std;
int partition(int arr[], int low, int high)
{int i = low;int j = high;int base = arr[low];if (low < high){while (i < j){while (i < j && arr[j] >= base){j--;}if (i < j){arr[i++] = arr[j];}while (i < j && arr[i] < base){i++;}if (i < j){arr[j--] = arr[i];}}arr[i] = base;}return i;
}void QuickSort(int* arr, int low, int high)
{if (low < high){int index = partition(arr, low, high);QuickSort(arr, low, index - 1);QuickSort(arr, index + 1, high);}
}int main()
{int arr[] = { 163,161,158,165,171,170,163,159,162 };int len = sizeof(arr) / sizeof(arr[0]);//int index = partition(arr, 0, len - 1);QuickSort(arr, 0, len - 1);cout << "Executing the Quick Sort, result as" << endl;for (int i = 0; i < len; i++){cout << arr[i] << " ";}system("pause");return 0;
}

各大算法對比圖

在這里插入圖片描述

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

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

相關文章

k8s-pod詳解

一、Pod基本概念&#xff1a; 1.pod介紹&#xff1a; Pod是kubernetes中最小的資源管理組件&#xff0c;Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的&#xff0c;例如&am…

電賽經驗分享——賽前準備

? 大家好哇&#xff01;我是小光&#xff0c;想要成為系統架構師的嵌入式愛好者。 ?在之前的電賽中取得了省一的成績&#xff0c;本文對電賽比賽前需要準備什么做一個經驗分享。 ?感謝你的閱讀&#xff0c;不對的地方歡迎指正。 加入小光嵌入式交流群&#xff08;qq群號&…

在線人才測評在企業招聘和大學生求職中的應用場景

每年的春招秋招&#xff0c;都是畢業生們忙著找工作的季節&#xff0c;相比社招來說&#xff0c;春招秋招是每個畢業生務必重視的機會&#xff0c;大廠名企畢竟名額有限&#xff0c;如果找到自己心儀的職業崗位&#xff0c;作為畢業生就必須提前準備&#xff0c;深入了解招聘的…

五管OTA輸入極性快速判斷

做CMFB還有負反饋的時候曾經在判斷輸入輸出極性上吃了大虧&#xff0c;直接做實驗波形正確就是輸入正端&#xff0c;全差分就不用考慮這么多了 和彎折&#xff0c;形狀類似7&#xff0c;相同方向輸入正端&#xff0c;相反的就是輸入負端&#xff0c;輸出也是和輸入負端一個方向…

【NLP】人機對話

概念 機器翻譯就是用計算機把一種語言翻譯成另外一種語言的技術 機器翻譯的產生與發展 17 世紀&#xff0c;笛卡爾與萊布尼茨試圖用統一的數字代碼來編寫詞典 1930 機器腦 1933 蘇聯發明家特洛陽斯基用機械方法將一種語言翻譯為另一種語言 1946 ENIAC 誕生 1949 機器翻譯問題…

香蕉成熟度檢測YOLOV8NANO

香蕉成熟度檢測YOLOV8NANO&#xff0c;采用YOLOV8NANO訓練&#xff0c;得到PT模型&#xff0c;然后轉換成ONNX模型&#xff0c;讓OEPNCV調用&#xff0c;從而擺脫PYTORCH依賴&#xff0c;支持C。python&#xff0c;安卓開發。能檢測六種香蕉類型freshripe freshunripe overripe…

Vita-CLIP: Video and text adaptive CLIP via Multimodal Prompting

標題&#xff1a;Vita-CLIP: 通過多模態提示進行視頻和文本自適應CLIP 源文鏈接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Wasim_Vita-CLIP_Video_and_Text_Adaptive_CLIP_via_Multimodal_Prompting_CVPR_2023_paper.pdfhttps://openaccess.thecvf.…

sw布爾減

可能最有效率還是草圖邊界線,然后用草圖做分割

ue5 中ps使用記錄貼

一、快捷鍵記錄 放大圖形 ctrlalt空格 放大圖形 縮小視口 ctrl空格 ctrlD 取消選區 ctrlt縮小文字 w魔棒工具 選擇魔棒的時候把容差打開的多一點 二、案例 移動文字 在相應的圖層選擇 移動文字 修改圖片里的顏色 在通道里拷貝紅色通道&#xff0c;復制紅色通道粘貼給正常圖…

記錄Hbase出現HMaster一直初始化,日志打印hbase:meta,,1.1588230740 is NOT online問題的解決

具體錯誤 hbase:meta,,1.1588230740 is NOT online&#xff1b; state{1588230740 stateOPEN, ...... 使用 hbase 2.5.5 &#xff0c;hdfs和hbase分離兩臺服務器。 總過程 1. 問題發現 在使用HBase的程序發出無法進行插入到HBase操作日志后檢查HBase狀況。發現master節點和r…

大模型應用商業化落地關鍵:給企業帶來真實的業務價值

2024 年被很多人稱為大模型應用的元年&#xff0c;毫無疑問&#xff0c;大模型已經成為共識&#xff0c;下一步更急迫的問題也擺在了大家的面前——大模型到底能夠用在哪&#xff1f;有哪些場景能落地&#xff1f;怎么做才能創造真正的價值&#xff1f; 在剛剛過去的 AICon 全…

【排序算法】快速排序(四個版本以及兩種優化)含動圖)

制作不易&#xff0c;三連支持一下吧&#xff01;&#xff01;&#xff01; 文章目錄 前言一.快速排序Hoare版本實現二.快速排序挖坑法版本實現三.快速排序前后指針版本實現四.快速排序的非遞歸版本實現五.兩種優化總結 前言 前兩篇博客介紹了插入和選擇排序&#xff0c;這篇博…

halcon配合yolov8導出onnx模型檢測物體

1.工業上多數視覺開發都是用halcon開發的&#xff0c;halcon本身也有自己的深度學習網絡&#xff0c;至于halcon如果不使用本身的深度學習&#xff0c;使用其他網絡導出的onnx模型怎樣配合使用&#xff1f;本文基于yolov8寫一個列子。 2。創建輸入數據的轉換代碼 #region 創建輸…

Nginx高可用性架構:實現負載均衡與故障轉移的探索

隨著網絡應用的不斷發展和用戶訪問量的增長&#xff0c;如何確保系統的高可用性、實現負載均衡以及快速響應故障轉移成為了每個運維和開發團隊必須面對的挑戰。Nginx作為一款高性能的HTTP和反向代理服務器&#xff0c;憑借其強大的功能和靈活的配置&#xff0c;成為了實現這些目…

題目:填空練習(指向指針的指針)

題目&#xff1a;填空練習&#xff08;指向指針的指針&#xff09; There is no nutrition in the blog content. After reading it, you will not only suffer from malnutrition, but also impotence. The blog content is all parallel goods. Those who are worried about …

【bugfix】/usr/local/bin/docker-compose:行1: html: 沒有那個文件或目錄

前言 在使用 docker-compose 管理容器化應用時&#xff0c;偶爾會遇到一些意想不到的錯誤&#xff0c;比如當嘗試運行 docker-compose 命令時&#xff0c;終端非但沒有展示預期的輸出&#xff0c;反而出現類似網頁錯誤的信息。這類問題通常與 docker-compose 的安裝或配置有關…

首都師范大學聘請旅美經濟學家向凌云為客座教授

2024年4月17日&#xff0c;首都師范大學客座教授聘任儀式在首都師范大學資源環境與旅游學院舉行。首都師范大學資源環境與旅游學院院長呂拉昌主持了儀式&#xff0c;并為旅美經濟學家向凌云教授頒發了聘書。 呂拉昌院長指出&#xff0c;要貫徹教育部產學研一體化戰略&#xff0…

數據庫工具類

public interface DbMapper {/*** 查詢數據庫類型*/String queryDbType(); }<select id"queryDbType" resultType"java.lang.String">select<choose><when test"_databaseId mysql">mysql</when><when test"_d…

虛擬機Centos擴展磁盤空間

虛擬機空間&#xff1a;現sda大小20G&#xff0c;因課程需要擴容 在虛擬機擴容中&#xff0c; 新增一塊硬盤 和 直接在原有硬盤基礎上擴容是一樣的&#xff08;只不過在原有硬盤上擴容需要關機才可以執行&#xff09;&#xff1b; 但兩者都最好先做數據備份或快照&#xff0c…

夏令營復習coding 算法第一天-狀態:新奇

T1:bubble冒泡排序 &#xff08;1&#xff09;思路&#xff1a;兩次循環&#xff0c;外層循環從后面開始-作為一個支點&#xff0c;內層循環每次將當前需要排序的最大的那個元素一步步移動到該支點&#xff0c;最終升序排列完成 &#xff08;2&#xff09;代碼: #include &l…