日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

9个元素换6次达到排序序列_程序员必须掌握的:10大排序算法梳理已整理好

發(fā)布時(shí)間:2024/1/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 9个元素换6次达到排序序列_程序员必须掌握的:10大排序算法梳理已整理好 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

從數(shù)組中選擇最小元素,將它與數(shù)組的第一個(gè)元素交換位置。再?gòu)臄?shù)組剩下的元素中選擇出最小的元素,將它與數(shù)組的第二個(gè)元素交換位置。不斷進(jìn)行這樣的操作,直到將整個(gè)數(shù)組排序。

動(dòng)態(tài)過(guò)程

算法原理參考:圖解選擇排序。

代碼實(shí)現(xiàn)

// 選擇排序public static void selectSort(int[] arr) { for (int i = 0; i < arr.length-1; i++) { int k = i; for (int j = i+1; j < arr.length; j++) { if (arr[j] < arr[k]) { k = j; } } if (k != i) { int temp = arr[i]; arr[i] = arr[k]; arr[k] = temp; } }}

1|2冒泡排序

算法思想

從左到右不斷交換相鄰逆序的元素,在一輪的循環(huán)之后,可以讓未排序的最大元素上浮到右側(cè)。在一輪循環(huán)中,如果沒(méi)有發(fā)生交換,那么說(shuō)明數(shù)組已經(jīng)是有序的,此時(shí)可以直接退出。

算法原理參考:圖解冒泡排序。

代碼實(shí)現(xiàn)

// 冒泡排序public static void bubbleSort(int[] arr) { // 設(shè)置每次冒泡的終止點(diǎn) for (int i = arr.length-1; i > 0; i--) { boolean change = false; // 從起點(diǎn)開(kāi)始冒泡 for (int j = 0; j < i; j++) { if (arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; if (change == false) { change = true; } } } // 如果本次無(wú)交換,則表示已有序,排序完成 if (!change) { return; } }}

1|3插入排序

算法思想

通過(guò)構(gòu)建有序序列,對(duì)于未排序數(shù)據(jù),在已排序序列中從后向前掃描,找到相應(yīng)位置并插入。每步將一個(gè)待排序的元素,按其排序碼大小插入到前面已經(jīng)排好序的一組元素的適當(dāng)位置上去,直到元素全部插入為止。

算法原理參考:圖解插入排序。

代碼實(shí)現(xiàn)

// 插入排序public static void insertionSort(int[] arr) { // 從第二個(gè)元素開(kāi)始為它們找位置 for (int i = 1; i < arr.length; i++) { // 記住當(dāng)前元素 int temp = arr[i]; int j; // 從當(dāng)前元素左邊第一個(gè)元素開(kāi)始,向左找位置 for (j = i-1; j >= 0 && arr[j] > temp; j--) { arr[j+1] = arr[j]; } // 找到合適位置后,將當(dāng)前元素插入 arr[j+1] = temp; }}

1|4希爾排序

算法思想

又稱“分組插入排序”,先將整個(gè)待排元素序列分割成若干個(gè)子序列(由相隔某個(gè)“增量”的元素組成的)分別進(jìn)行直接插入排序,然后依次縮減增量再進(jìn)行排序,待整個(gè)序列中的元素基本有序(增量足夠小)時(shí),再對(duì)全體元素進(jìn)行一次直接插入排序。

算法原理參考:圖解希爾排序。

這個(gè)排序算法較難理解,建議讀者在本子上依照代碼的執(zhí)行過(guò)程,把排序過(guò)程動(dòng)手畫一遍,這應(yīng)該是理解其本質(zhì)最快的方法了。

代碼實(shí)現(xiàn)

// 希爾排序public static void shellSort(int[] arr) { // 增量控制,每次減半 for (int gap = arr.length/2; gap > 0; gap /= 2) { // 步長(zhǎng)控制,從gap開(kāi)始向后移動(dòng) for (int i = gap; i < arr.length; i++) { int temp = arr[i]; int j; // 起始指針控制,向左插入排序(找位置) for (j = i-gap; j >= 0 && arr[j] > temp; j -= gap) { arr[j+gap] = arr[j]; } arr[j+gap] = temp; } }}

1|5歸并排序

算法思想

該算法采用經(jīng)典的分治(divide-and-conquer)策略,分:問(wèn)題分成一些小的問(wèn)題然后遞歸求解,治:將分的階段得到的各答案"修補(bǔ)"在一起,即分而治之。將序列遞歸拆半分成多個(gè)子序列,再將各個(gè)子序列排序后歸并疊加,最后歸并所有子序列,排序完成。

算法原理參考:圖解歸并排序。

代碼實(shí)現(xiàn)

// 歸并排序public static void mergeSort(int[] arr, int left, int right) { if (left < right) { int mid = (left + right) / 2; // 分 mergeSort(arr, left, mid); mergeSort(arr, mid+1, right); // 治 merge(arr, left, mid, right); }}public static void merge(int[] arr, int left, int mid, int right) { // 臨時(shí)數(shù)組 int[] temp = new int[right-left+1]; // 左、右指針 int i = left; int j = mid+1; int k = 0; // 將兩段數(shù)據(jù)按序?qū)懭肱R時(shí)數(shù)組 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[k++] = arr[i++]; }else { temp[k++] = arr[j++]; } } // 剩余數(shù)據(jù)寫入 while (i <= mid) { temp[k++] = arr[i++]; } while (j <= right) { temp[k++] = arr[j++]; } // 更新arr數(shù)組 k = 0; while (left <= right) { arr[left++] = temp[k++]; }}

1|6快速排序

算法思想

以第一個(gè)元素為基準(zhǔn),左右指針向中間移動(dòng)掃描,小于基準(zhǔn)元素的放到左邊,大于基準(zhǔn)元素的放到右邊,最后將基準(zhǔn)元素放到中間,這個(gè)位置也就是基準(zhǔn)元素的合適位置。此時(shí)數(shù)據(jù)以基準(zhǔn)元素為間隔,分為左右兩部分(不包括基準(zhǔn)元素),然后分別對(duì)左右兩部分?jǐn)?shù)據(jù)分別執(zhí)行此過(guò)程,直到數(shù)據(jù)不能再分,此時(shí)排序完成。

算法原理參考:圖解快速排序。

代碼實(shí)現(xiàn)

// 快速排序public static void quickSort(int[] arr, int left, int right) { if (left < right) { int index = getIndex(arr, left, right); quickSort(arr, left, index-1); quickSort(arr, index+1, right); }}public static int getIndex(int[] arr, int left, int right) { // 得到基準(zhǔn)元素 int item = arr[left]; // 向中間移動(dòng),調(diào)整位置,找到基準(zhǔn)元素的位置 while (left < right) { while (left < right && arr[right] >= item) { right--; } arr[left] = arr[right]; while (left < right && arr[left] <= item) { left++; } arr[right] = arr[left]; } // 放置基準(zhǔn)元素 arr[left] = item; return left;}

1|7堆排序

算法思想

將待排序序列構(gòu)造成一個(gè)大頂堆,此時(shí),整個(gè)序列的最大值就是堆頂?shù)母?jié)點(diǎn)。將其與末尾元素進(jìn)行交換,此時(shí)末尾就為最大值。然后將剩余n-1個(gè)元素重新構(gòu)造成一個(gè)堆,這樣會(huì)得到n個(gè)元素的次小值。如此反復(fù)執(zhí)行,便能得到一個(gè)有序序列了。

算法原理參考:圖解堆排序。

代碼實(shí)現(xiàn)

// 堆排序public static void heapSort(int[] arr) { // 1.構(gòu)建大頂堆 for (int i = arr.length/2-1; i >= 0; i--) { adjust(arr, i, arr.length); } // 2.調(diào)整堆結(jié)構(gòu),交換頂元素與末尾元素 for (int j = arr.length-1 ; j > 0; j--) { int temp = arr[j]; arr[j] = arr[0]; arr[0] = temp; adjust(arr, 0, j); }}public static void adjust(int[] arr, int i, int length) { int temp = arr[i]; for (int k = 2*i+1; k < length; k = 2*k+1) { if (k+1 < length && arr[k+1] > arr[k]) { k++; } if (arr[k] > temp) { arr[i] = arr[k]; i = k; }else { break; } } arr[i] = temp;}

1|8計(jì)數(shù)排序

算法思想

計(jì)數(shù)排序要求輸入的數(shù)據(jù)必須是有確定范圍的整數(shù)。

找出待排序的數(shù)組中最大和最小的元素;統(tǒng)計(jì)數(shù)組中每個(gè)值為i的元素出現(xiàn)的次數(shù),存入數(shù)組C的第i項(xiàng);對(duì)所有的計(jì)數(shù)累加(從C中的第一個(gè)元素開(kāi)始,每一項(xiàng)和前一項(xiàng)相加);反向填充目標(biāo)數(shù)組:將每個(gè)元素i放在新數(shù)組的第C(i)項(xiàng),每放一個(gè)元素就將C(i)減去1。

算法原理參考:圖解計(jì)數(shù)排序。

代碼實(shí)現(xiàn)

// 計(jì)數(shù)排序public static int[] countSort(int[] src) { // 計(jì)算最大值與最小值 int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i = 0; i < src.length; i++){ max = Math.max(max, src[i]); min = Math.min(min, src[i]); } // 數(shù)組中的數(shù)據(jù)范圍 int range = max - min + 1; // count[i]表示數(shù)組src中數(shù)據(jù)min + i的個(gè)數(shù) int[] count = new int[range]; for (int value : src) { count[value - min]++; } // 累計(jì)變形,使得count[i]保存src中小于等于min + i的數(shù)據(jù)的個(gè)數(shù) for (int i = 1; i < range; i++) { count[i] += count[i - 1]; } // 結(jié)果數(shù)組 int[] res = new int[src.length]; // 倒序遍歷原數(shù)組,保持排序的穩(wěn)定性 for (int i = src.length - 1; i >= 0; i--) { // 獲取數(shù)據(jù)在count數(shù)組中的索引 int index = src[i] - min; // 個(gè)數(shù)減1 count[index]--; // 數(shù)據(jù)src[i]排序后的索引是count[index] res[count[index]] = src[i]; } return res;}

1|9桶排序

算法思想

桶排序是計(jì)數(shù)排序的擴(kuò)展版本,計(jì)數(shù)排序可以看成每個(gè)桶只存儲(chǔ)相同元素,而桶排序每個(gè)桶存儲(chǔ)一定范圍的元素,通過(guò)映射函數(shù),將待排序數(shù)組中的元素映射到各個(gè)對(duì)應(yīng)的桶中,對(duì)每個(gè)桶中的元素進(jìn)行排序,最后將非空桶中的元素逐個(gè)放入原序列中。

桶排序需要盡量保證元素分散均勻,否則當(dāng)所有數(shù)據(jù)集中在同一個(gè)桶中時(shí),桶排序失效。

算法原理參考:圖解桶排序。

代碼實(shí)現(xiàn)

// 桶排序public static void bucketSort(int[] arr){ // 計(jì)算最大值與最小值 int max = Integer.MIN_VALUE; int min = Integer.MAX_VALUE; for(int i = 0; i < arr.length; i++){ max = Math.max(max, arr[i]); min = Math.min(min, arr[i]); } // 計(jì)算桶的數(shù)量,并創(chuàng)建桶 int bucketNum = (max - min) / arr.length + 1; ArrayList> bucketArr = new ArrayList<>(bucketNum); for(int i = 0; i < bucketNum; i++){ bucketArr.add(new ArrayList()); } // 將每個(gè)元素放入桶 for(int i = 0; i < arr.length; i++){ int num = (arr[i] - min) / (arr.length); bucketArr.get(num).add(arr[i]); } // 對(duì)每個(gè)桶進(jìn)行排序 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++){ arr[index++] = bucketArr.get(i).get(j); } } }

1|10基數(shù)排序

算法思想

基數(shù)排序可以看成是桶排序的擴(kuò)展,以整數(shù)排序?yàn)槔?#xff0c;主要思想是將整數(shù)按位數(shù)劃分,準(zhǔn)備 10 個(gè)桶,代表 0 - 9,根據(jù)整數(shù)個(gè)位數(shù)字的數(shù)值將元素放入對(duì)應(yīng)的桶中,之后按照輸入賦值到原序列中,依次對(duì)十位、百位等進(jìn)行同樣的操作,最終就完成了排序的操作。

  算法原理參考:圖解基數(shù)排序。

代碼實(shí)現(xiàn)

public static void radixSort(int[] arr) { if (arr == null || arr.length < 2) { return; } radixSort(arr, 0, arr.length - 1, maxbits(arr));} // 計(jì)算最大位數(shù)public static int maxbits(int[] arr) { int max = Integer.MIN_VALUE; for (int i = 0; i < arr.length; i++) { max = Math.max(max, arr[i]); } int res = 0; while (max != 0) { res++; max /= 10; } return res;}// 基數(shù)排序public static void radixSort(int[] arr, int begin, int end, int digit) { final int radix = 10; int i = 0, j = 0; int[] count = new int[radix]; int[] bucket = new int[end - begin + 1]; // 依次遍歷每個(gè)位數(shù) for (int d = 1; d <= digit; d++) { for (i = 0; i < radix; i++) { count[i] = 0; } // 統(tǒng)計(jì)數(shù)量 for (i = begin; i <= end; i++) { j = getDigit(arr[i], d); count[j]++; } // 計(jì)算位置 for (i = 1; i < radix; i++) { count[i] = count[i] + count[i - 1]; } // 記錄到對(duì)應(yīng)位置 for (i = end; i >= begin; i--) { j = getDigit(arr[i], d); count[j]--; bucket[count[j]] = arr[i]; } for (i = begin, j = 0; i <= end; i++, j++) { arr[i] = bucket[j]; } }}// 獲取位數(shù)數(shù)值public static int getDigit(int x, int d) { return ((x / ((int) Math.pow(10, d - 1))) % 10);}

2|0排序算法梳理

2|1復(fù)雜度分析

2|2算法分類及適用場(chǎng)景

  ★ 選擇、冒泡、插入、希爾、歸并、快速、堆排序都是基于比較的排序

    ? 平均時(shí)間復(fù)雜度最低O(nlogn)。

    ? 適用于所有可比較的對(duì)象。

  ★ 計(jì)數(shù)排序、桶排序、基數(shù)排序不是基于比較的排序

    ? 使用空間換時(shí)間,某些時(shí)候,平均時(shí)間復(fù)雜度可以低于O(nlogn)。

    ? 適用于正整數(shù)的比較。

2|3穩(wěn)定性分析

  ? 不穩(wěn)定的排序算法有:快速排序、希爾排序、選擇排序、堆排序。

    ? 巧記:快『快速排序』、些『希爾排序』、選『選擇排序』、堆『堆排序』。

  ? 穩(wěn)定的排序算法有:冒泡排序、插入排序、歸并排序、計(jì)數(shù)排序、桶排序、基數(shù)排序。

總結(jié)

以上是生活随笔為你收集整理的9个元素换6次达到排序序列_程序员必须掌握的:10大排序算法梳理已整理好的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。