数据结构Java03【(时间、空间复杂度),排序(冒泡、快速、插入、希尔、选择、归并、基数、队列基数)】
學習地址:【數據結構與算法基礎-java版】? ? ? ? ? ? ? ? ??🚀數據結構--Java專欄🚀
- 筆記01【01-09】【概述、數組基本使用】【源碼、課件】
- 筆記02【10-18】【棧、隊列、單鏈表(增刪節點)、循環鏈表、雙向循環鏈表、遞歸(斐波那契、漢諾塔)】
- 筆記03【19-27】【(時間、空間復雜度);八大排序(冒泡、快速、插入、希爾、選擇、歸并、基數、隊列基數)】
- 筆記04【28-33】【樹結構(二叉樹)概述、創建、遍歷、查找節點、刪除節點】
- 筆記05【34-39】【順序存儲二叉樹概述、二叉樹遍歷、堆排序、線索二叉樹實現及遍歷】
- 筆記06【40-48】【赫夫曼樹、概述、原理分析、代碼實現(數據壓縮、創建編碼表、解碼、壓縮文件、解壓文件)】
- 筆記07【49-54】【二叉排序樹(添加、查找、刪除節點)】
- 筆記08【55-57】【二叉平衡樹(AVL)-概述、單旋轉、雙旋轉】
- 筆記09【58-60】【計算機中數據的存儲原理、2-3樹的插入原理、B樹和B+樹】
- 筆記10【61-63】【哈希表概述、散列函數的設計、散列沖突解決方案】
- 筆記11【64-67】【圖結構概述、圖遍歷原理(BFS\DFS)、圖遍歷代碼實現】
目? ?錄
P19-3.1算法的時間復雜度和空間復雜度
1、時間復雜度
1.1、忽略常數
1.2、忽略低次項
1.3、忽略系數
2、衡量一個算法的優劣(時間復雜度、空間復雜度)
2.1、語句頻度T(n)
2.2、時間復雜度
2.3、常見的時間復雜度
2.4、時間復雜度
2.5、平均時間復雜度和最壞時間復雜度
P20-3.2排序算法之冒泡排序
P21-3.3排序算法之快速排序
P22-3.4排序算法之插入排序
P23-3.5排序算法之希爾排序
P24-3.6排序算法之選擇排序
P25-3.7排序算法之歸并排序
P26-3.8排序算法之基數排序
P27-3.9基數排序之隊列實現
P19-3.1算法的時間復雜度和空間復雜度
1、時間復雜度
1.1、忽略常數
1.2、忽略低次項
1.3、忽略系數
2、衡量一個算法的優劣(時間復雜度、空間復雜度)
一、事后統計的方法
二、事前分析估算的方法
?
計算1-100所有數字之和
2.1、語句頻度T(n)
一個算法中的語句執行次數稱為語句頻度,記為T(n)。
2.2、時間復雜度
?一般情況下,算法中的基本操作語句的重復執行次數是問題規模n的某個函數,用T(n)表示,若有某個輔助函數f(n),使得當n趨近于無窮大時,T(n) / f(n) 的極限值為不等于零的常數,則稱f(n)是T(n)的同數量級函數。記作 T(n)=O( f(n) ),稱O( f(n) )? 為算法的漸進時間復雜度,簡稱時間復雜度。
T(n) 不同,但時間復雜度可能相同。 如:T(n)=n2+5n+6 與 T(n)=3n2+3n+2 它們的T(n)?不同,但時間復雜度相同,都為O(n2)。
2.3、常見的時間復雜度
常數階O(1)
對數階O(log2n)
線性階O(n)
線性對數階O(nlog2n)
平方階O(n2)
立方階O(n3)
k次方階O(nk)
指數階O(2n)
隨著問題規模n的不斷增大,上述時間復雜度不斷增大,算法的執行效率越低。
2.4、時間復雜度
計算時間復雜度的方法:
用常數1代替運行時間中的所有加法常數?
修改后的運行次數函數中,只保留最高階項?
去除最高階項的系數
2.5、平均時間復雜度和最壞時間復雜度
平均時間復雜度是指所有可能的輸入實例均以等概率出現的情況下,該算法的運行時間。
最壞情況下的時間復雜度稱最壞時間復雜度。一般討論的時間復雜度均是最壞情況下的時間復雜度。?這樣做的原因是:最壞情況下的時間復雜度是算法在任何輸入實例上運行時間的界限,這就保證了算法的運行時間不會比最壞情況更長。
P20-3.2排序算法之冒泡排序
package demo4;import java.util.Arrays;public class BubbleSort {public static void main(String[] args) {int[] arr = new int[] { 5, 7, 2, 9, 4, 1, 0, 5, 7 };System.out.println(Arrays.toString(arr));bubbleSort(arr);System.out.println(Arrays.toString(arr));}/**冒泡排序 * 共需要比較length-1輪* 5,7,2,9,4,1,0,5,7 【5、7】 * 5,7,2,9,4,1,0,5,7 【7、2】* 5,2,7,9,4,1,0,5,7 ...* 5,2,7,4,1,0,5,7,9* 2,5 */public static void bubbleSort(int[] arr) {// 控制共比較多少輪for (int i = 0; i < arr.length - 1; i++) {// 控制比較的次數for (int j = 0; j < arr.length - 1 - i; j++) { // 減i,比較過的數字,不再進行比較if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;}}}}// 冒泡排序優化public static void bubbleSort2(int[] arr) {// 控制共比較多少輪for (int i = 0; i < arr.length - 1; i++) {boolean flag = false;// 控制比較的次數for (int j = 0; j < arr.length - 1 - i; j++) { // 減i,比較過的數字,不再進行比較if (arr[j] > arr[j + 1]) {int temp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = temp;flag = true; // 加入標記 }}if(flag) { // 如果沒有交換過元素,則已經有序!return;}}}}冒泡排序優化:https://blog.csdn.net/hansionz/article/details/80822494?
P21-3.3排序算法之快速排序
low、high重合,數組按照基數分配完畢。比基數大的數字,在右邊;比基數小的數字,在左邊;繼續遞歸。
設定一個基準數a。【通常取第一個數字!】
比a大的數字,往右移動;比a小的數字,往左移動!遞歸!!!
設置 前后 2個 標記,標記重合,進行下一次 遞歸!【遞歸結束條件:開始位置==結束位置】
package demo4;import java.util.Arrays;public class QuickSort {public static void main(String[] args) {int[] arr = new int[] { 3, 4, 6, 7, 2, 7, 2, 8, 0, 9, 1 };quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void quickSort(int[] arr, int start, int end) {if (start < end) {int stard = arr[start]; // 把數組中的第0個數字做為標準數【從數組的開始位置取標準數】int low = start; // 記錄坐標-記錄需要排序的下標int high = end; // 記錄坐標while (low < high) { // 循環找比標準數大的數和比標準數小的數【高右低左】// 1、右邊的數字比標準數大,則數字不需要移動,high--// stard <= arr[high]:基準數要小于右邊指針所指的數字while (low < high && stard <= arr[high]) {high--;//基準數小于右邊指針所指的數字,high--前移}arr[low] = arr[high];// 使用右邊的數字替換左邊的數// 2、如果左邊的數字比標準數小,則數字不需要移動,low++while (low < high && arr[low] <= stard) {low++;//下標右移}arr[high] = arr[low];}// low、high重合---把標準數賦給低所在的位置的元素arr[low] = stard;// low、high重合---根據low與high所在的下標-處理所有的小的數字-從開始位置~低的位置quickSort(arr, start, low);// low、high重合---根據low與high所在的下標-處理所有的大的數字-從開始位置~高的位置quickSort(arr, low + 1, end);}}}P22-3.4排序算法之插入排序
認為所有的數字,都是有序的。將數字依次往前移動,一個一個插入到前面的有序序列中!
從第2個數字開始,把之后的數字挨個遍歷一遍。遍歷的時候,認為前面的數字都是有序的。
在遍歷下一個數字的時候,如果該數字比當前數字更小,則將該數字往前移動,直到前面的數字序列有序;
在遍歷下一個數字的時候,如果該數字比當前數字更大,則將該數字往后移動,直到已經遍歷的數字序列有序。
?
// 把臨時變量(外層for循環的當前元素)賦給不滿足條件的后一個元素
arr[j + 1] = temp;?
P23-3.5排序算法之希爾排序
將 數組 分為 4部分,每一部分都進行插入排序!
第1輪步長:4;【9/2 == 4】
第2輪步長:2;【4/2 == 2】
第3輪步長:1。【2/2 == 1】
package demo4;import java.util.Arrays;public class ShellSort {public static void main(String[] args) {int[] arr = new int[] { 3, 5, 2, 7, 8, 1, 2, 0, 4, 7, 4, 3, 8 };System.out.println(Arrays.toString(arr));shellSort(arr);System.out.println(Arrays.toString(arr));}public static void shellSort(int[] arr) {int k = 1;// 遍歷所有的步長for (int d = arr.length / 2; d > 0; d /= 2) {// 遍歷所有元素for (int i = d; i < arr.length; i++) {// 遍歷本組中所有的元素for (int j = i - d; j >= 0; j -= d) {// 如果當前元素大于加上步長后的那個元素if (arr[j] > arr[j + d]) {int temp = arr[j];arr[j] = arr[j + d];arr[j + d] = temp;}}}System.out.println("第" + k + "次排序結果:" + Arrays.toString(arr));k++;}}}P24-3.6排序算法之選擇排序
簡單選擇排序
標注一個相對較小的數字(x),依次向后找,找一個 比 此數字(x) 還小的數字,遍歷完此數組,將找到的比x小 且 最小的數字,移至最前面。接著從上一個找到的最小的數字,開始往后找,每次只找數組中最小的元素,將其移至前面。一直這樣...
從第1個數字,開始往后找。
從第2個數字,開始往后找。
從第3個數字,開始往后找。
把 所有的數字 遍歷一遍,有多少數字,便選多少次最小的數字。
package demo4;import java.util.Arrays;public class SelectSort {public static void main(String[] args) {int[] arr = new int[] { 3, 4, 5, 7, 1, 2, 0, 3, 6, 8 };selectSort(arr);System.out.println(Arrays.toString(arr));}// 選擇排序public static void selectSort(int[] arr) {// 遍歷所有的數for (int i = 0; i < arr.length; i++) {int minIndex = i;// 把當前遍歷的數和后面所有的數依次進行比較,并記錄下最小的數的下標for (int j = i + 1; j < arr.length; j++) {// 如果后面比較的數比記錄的最小的數小。if (arr[minIndex] > arr[j]) {// 記錄下最小的那個數的下標minIndex = j;}}// 如果最小的數和當前遍歷數的下標不一致,說明下標為minIndex的數比當前遍歷的數更小。if (i != minIndex) {int temp = arr[i];arr[i] = arr[minIndex];arr[minIndex] = temp;}}}}P25-3.7排序算法之歸并排序
package demo4;import java.util.Arrays;public class MergeSort {public static void main(String[] args) {int[] arr = new int[] { 1, 3, 5, 2, 4, 6, 8, 10 };//【3 1】System.out.println(Arrays.toString(arr));mergeSort(arr, 0, arr.length - 1);//【0 0 1】System.out.println(Arrays.toString(arr));}// 歸并排序public static void mergeSort(int[] arr, int low, int high) {int middle = (high + low) / 2;if (low < high) {// 處理左邊mergeSort(arr, low, middle);// 處理右邊mergeSort(arr, middle + 1, high);// 歸并merge(arr, low, middle, high);}}public static void merge(int[] arr, int low, int middle, int high) {// 用于存儲歸并后的臨時數組int[] temp = new int[high - low + 1];// 記錄第一個數組中需要遍歷的下標int i = low;// 記錄第二個數組中需要遍歷的下標int j = middle + 1;// 用于記錄在臨時數組中存放的下標int index = 0;// 遍歷兩個數組取出小的數字,放入臨時數組中while (i <= middle && j <= high) {// 第一個數組的數據更小if (arr[i] <= arr[j]) {// 把小的數據放入臨時數組中temp[index] = arr[i];// 讓下標向后移一位;i++;} else {temp[index] = arr[j];j++;}index++;}// 處理多余的數據while (j <= high) {temp[index] = arr[j];j++;index++;}while (i <= middle) {temp[index] = arr[i];i++;index++;}// 把臨時數組中的數據重新存入原數組for (int k = 0; k < temp.length; k++) {arr[k + low] = temp[k];}}}P26-3.8排序算法之基數排序
大小都有,數字位數不一樣!
排序次數,取決于,數組中最大數字的位數!
?
先找出數組中最大的數字【int max = Integer.MIN_VALUE;】,
將數字轉為字符串---計算位數【int maxLength = (max + "").length();】===》確定循環次數。
第1次,按照個位進行排序!
第2次,按照十位進行排序!
第3次,按照十位進行排序!
余數:0~9? ?==>? ?最多需要10個數組
package demo4;import java.util.Arrays;public class RadixSort {public static void main(String[] args) {int[] arr = new int[] { 23, 6, 189, 45, 9, 287, 56, 1, 798, 34, 65, 652, 5 };radixSort(arr);System.out.println(Arrays.toString(arr));}public static void radixSort(int[] arr) {// 存最數組中最大的數字int max = Integer.MIN_VALUE;for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}// 計算最大數字是幾位數int maxLength = (max + "").length();// 用于臨時存儲數據的二維數組int[][] temp = new int[10][arr.length];// arr.length 避免 空指針異常// 用于記錄在temp中相應的數組中存放的數字的數量int[] counts = new int[10];// 根據最大長度的數決定比較的次數for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {// 把每一個數字分別計算余數for (int j = 0; j < arr.length; j++) {// 計算余數int ys = arr[j] / n % 10;// 把當前遍歷的數據放入指定的數組中temp[ys][counts[ys]] = arr[j];// 記錄數量counts[ys]++;}// 記錄取的元素需要放的位置int index = 0;// 把數字取出來for (int k = 0; k < counts.length; k++) {// 記錄數量的數組中當前余數記錄的數量不為0if (counts[k] != 0) {// 循環取出元素for (int l = 0; l < counts[k]; l++) {// 取出元素arr[index] = temp[k][l];// 記錄下一個位置index++;}// 把數量置為0counts[k] = 0;}}}}}P27-3.9基數排序之隊列實現
先放進去的先取;后放進去的后取。先進先出!!!隊列!!!
package demo4;import java.util.Arrays;import demo2.MyQueue;public class RadixQueueSort {public static void main(String[] args) {int[] arr = new int[] { 23, 6, 189, 45, 9, 287, 56, 1, 798, 34, 65, 652, 5 };radixSort(arr);System.out.println(Arrays.toString(arr));}public static void radixSort(int[] arr) {// 存最數組中最大的數字int max = Integer.MIN_VALUE;for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}// 計算最大數字是幾位數int maxLength = (max + "").length();// 用于臨時存儲數據的隊列的數組MyQueue[] temp = new MyQueue[10];// 為隊列數組賦值for (int i = 0; i < temp.length; i++) {temp[i] = new MyQueue();}// 根據最大長度的數決定比較的次數for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {// 把每一個數字分別計算余數for (int j = 0; j < arr.length; j++) {// 計算余數int ys = arr[j] / n % 10;// 把當前遍歷的數據放入指定的隊列中temp[ys].add(arr[j]);}// 記錄取的元素需要放的位置int index = 0;// 把所有隊列中的數字取出來for (int k = 0; k < temp.length; k++) {// 循環取出元素while (!temp[k].isEmpty()) {// 取出元素arr[index] = temp[k].poll();// 記錄下一個位置index++;}}}}}多謝觀看~~~
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的数据结构Java03【(时间、空间复杂度),排序(冒泡、快速、插入、希尔、选择、归并、基数、队列基数)】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构Java02【栈、队列、单链表(
- 下一篇: java美元兑换,(Java实现) 美元