查找与排序算法
本文章介紹了所有常用的查找和排序
排序的有寫 代碼 可以直接復制
這里重點說一句 希爾排序 yysd
如果對你有幫助 記得點贊收藏加關注哦 <( ̄▽ ̄)/
文章目錄
- 查找
- 線性查找
- 二分查找
- 插值查找
- 斐波那契查找
- 排序
- 選擇排序
- 冒泡排序
- 插入排序
- 希爾排序
- 歸并排序
- 快速排序
- 單路快速排序
- 雙路快速排序
- 三路快速排序
- 計數排序
- 桶排序
- 基數排序
查找
線性查找
一次for循環遍歷查找元素
二分查找
也叫折半查找
通過中間值不斷的將區間除以二 最后獲取要查找的值的位置
屬于有序查找
時間復雜度為o(log2 n)
mid=(low+high)/2
mid=low-(low-high)/2
插值查找
在二分的基礎上 根據比例查找
mid=low+(int)(1.0X(kay-a[low])/(a[high]-a[low])*(high-low))
斐波那契查找
在二分的基礎上 根據斐波那契數列進行分割
黃金比例查找
mid=low+0.624*(high-low)
排序
選擇排序
時間復雜度O(n^2)
空間復雜度 o(1)
穩定性 :不穩定
每一個元素和后面元素比較如果小或大則交換
package sort; import java.util.Arrays; public class Select_Sort {public static void main(String[] args) {int [] Arr={1,3,4,2,9,7,8};Select_sort(Arr);System.out.println(Arrays.toString(Arr));}private static void Select_sort(int[] arr) {//選擇排序for (int i = 0; i <arr.length-1 ; i++) {for (int j = i+1; j <arr.length ; j++) {if (arr[i]>arr[j]){swap(arr,i,j);}}}}private static void swap(int[] arr, int i, int j) {//交換int teme=arr[i];arr[i]=arr[j];arr[j]=teme;} }冒泡排序
時間復雜度O(n^2)
空間復雜度 o(1)
穩定性 :穩定
每個元素后一個元素比較 符合則交換
package sort; import java.util.Arrays; public class bubbleSort {public static void main(String[] args) {int [] Arr={1,3,4,2,9,7,8};bubbleSort(Arr);System.out.println(Arrays.toString(Arr));}private static void bubbleSort(int[] arr) {for (int i = 0; i <arr.length-1 ; i++) {for (int j = 0; j <arr.length-1-i ; j++) {if (arr[j]>arr[j+1]){swap(arr,j,j+1);}}}}private static void swap(int[] arr, int i, int j) {//交換int teme=arr[i];arr[i]=arr[j];arr[j]=teme;} }插入排序
時間復雜度O(n^2)
空間復雜度 o(1)
穩定性 :穩定
不斷的將當前值插入到前方合適的位置
package sort; import java.util.Arrays; public class InsertionSort {public static void main(String[] args) {int [] Arr={1,3,4,2,9,7,8};InsertionSort(Arr);System.out.println(Arrays.toString(Arr));}private static void InsertionSort(int[] arr) {//插入排序for (int i = 1; i <arr.length ; i++) {for (int j = i; j >0&& arr[j]<arr[j-1]; j--) {swap(arr,j,j-1);}}} private static void swap(int[] arr, int i, int j) {//交換int teme=arr[i];arr[i]=arr[j];arr[j]=teme;} }優化
不斷獲取最小值直接插入前方位置 且遇到大的提前終止
private static void InsertionSort(int[] arr) {//交換且提前終止插入排序int e=0;int j=0;for (int i = 1; i <arr.length ; i++) {e=arr[i];for ( j = i; j >0&& e<arr[j-1]; j--) {arr[j]=arr[j-1];}arr[j]=e;}}希爾排序
時間復雜度O(n^1.3)
空間復雜度 o(1)
穩定性 :不穩定
是簡單排序的改進版本,他與插入排序的不同之處在于 ,他會優先比較距離較遠的元素。
希爾排序右腳縮小增量排序
package sort; import java.util.Arrays; import java.util.Random; public class SheelSort {public static void main(String[] args) {int[] arr = new int[10];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}sheelSort(arr);System.out.println(Arrays.toString(arr));}private static void sheelSort(int[] arr) {for (int gap = arr.length/2; gap >0 ; gap--) {for (int i = gap; i <arr.length ; i++) {int j=i;int e=arr[j];while (j-gap>=0 &&arr[j-gap]>e){arr[j]=arr[j-gap];j=j-gap;}arr[j]=e;}}} }選擇部分排序 希爾
public static void shellSort(int[] arr, int l, int r) {int j=0;int e=0;int len=r-l+1;for (int gap = len; gap >0 ; gap=gap/2) {for (int i = gap; i <r ; i++) {j=i;e=arr[i];while ( j-gap>=0 &&arr[j-gap]>e){arr[j]=arr[j-gap];j=j-gap;}arr[j]=e;}} }歸并排序
時間復雜度O(nlog2n)
空間復雜度 o(n)
穩定性 :穩定
歸并排序是建立債歸并炒作是的一種有效的排序算法。
該算法是采用分治放的一個非常典型的的應用。
將已有序的子序列合并,得到完全有序的序列;即先使沒個子序列有序,再試子序列段間有序。若將兩個有序表合并成一個有序表,稱為2路歸并。
package sort; import java.util.Arrays; import java.util.Random; public class MergeSort {public static void main(String[] args) {int[] arr = new int[10];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}mergeSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}private static void mergeSort(int[] arr, int l, int r) {//歸并排序if (l >= r) {return;}int mid = (l + r) / 2;mergeSort(arr, l, mid);mergeSort(arr, mid + 1, r);merge(arr, l, mid, r);}private static void merge(int[] arr, int l, int mid, int r) {int[] arrcopy = Arrays.copyOf(arr, arr.length);int index = l;for (int i = l, j = mid + 1; i <= mid || j <= r; ) {if (i > mid) {arr[index++] = arrcopy[j];j++;} else if (j > r) {arr[index++] = arrcopy[i];i++;} else if (arrcopy[i] <= arrcopy[j]) {arr[index++] = arrcopy[i];i++;} else {arr[index++] = arrcopy[j];j++;}}} }小優化
private static void mergeSort(int[] arr, int l, int r) {//歸并排序if (l+1 >= r) {//有倆個元素時候直接排序int mid = (l + r) / 2;merge(arr, l, mid, r);//合并排序return;}int mid = (l + r) / 2;mergeSort(arr, l, mid);//制作分組1mergeSort(arr, mid + 1, r);//制作分組2if(arr[mid]>arr[mid+1]){//如果原本排序好了,則不需要排序merge(arr, l, mid, r);}}堆排序
二叉堆是一顆完全二叉樹
堆中的某個結點的值總是不大于父結點的值
package sort;import java.util.Arrays; import java.util.Random;public class HeepSort {public static void main(String[] args) {int[] arr = new int[10];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}heepSort(arr);System.out.println(Arrays.toString(arr));}private static int Len;private static void heepSort(int[] arr) {//1.將傳入的數組堆化 heapifyLen = arr.length;heapify(arr);//將最大值與最后一個元素交換 heapifyfor (int i = arr.length - 1; i >= 0; i--) {swap(arr, 0, i);Len--;heapify(arr);}}private static void heapify(int[] arr) {for (int i = Len - 1; i >= 0; i--) {siftDown(arr, i);}}private static void siftDown(int[] arr, int k) {while (leftChild(k) < Len) {int j = leftChild(k);if (j + 1 < Len && arr[j + 1] > arr[j]) {j = rightChild(k);}if (arr[k] < arr[j]) {swap(arr, k, j);k = j;} else {break;}}}private static int leftChild(int i) {return i * 2 + 1;}private static int rightChild(int i) {return i * 2 + 2;}private static int parent(int i) {return (i - 1) / 2;}private static void swap(int[] arr, int i, int j) {//交換int teme = arr[i];arr[i] = arr[j];arr[j] = teme;} }快速排序
時間復雜度O(nlog2n)
空間復雜度 o(1)
穩定性 :不穩定
通過一躺排序將待排序記錄獨立分隔成獨立的兩部分,七中一部分巨鹿的關鍵字均比另一部分小,比另一部分大 ,則可分別對這連部分記錄繼續進行排序,以達到整個序列有序
注意 l 和1 區分開不要看錯了
單路快速排序
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-iSCCgeSA-1638188775157)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20211129172314287-16381777981741.png)]
package sort;import java.util.Arrays; import java.util.Random;public class QuickSort1 {public static void main(String[] args) {int[] arr = new int[10];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void quickSort(int[] arr, int l, int r) {//單路快速排序if (l >= r) {return;}int p = partion(arr, l, r);quickSort(arr, l, p - 1);quickSort(arr, p + 1, r);}public static int partion(int[] arr, int l, int r) {int v = arr[l];int j = l;for (int i = l + 1; i <= r; i++) {if (arr[i] < v) {swap(arr, j + 1, i);j++;}}swap(arr, l, j);return j;}private static void swap(int[] arr, int i, int j) {//交換int teme = arr[i];arr[i] = arr[j];arr[j] = teme;} }優化
public static void quickSort(int[] arr, int l, int r) {//單路快速排序if (l >= r) {return;}int p = partion(arr, l, r);quickSort(arr, l, p - 1);quickSort(arr, p + 1, r);}private static int partion(int[] arr, int l, int r) {//2.優化 隨機數不固定 防止極端情況swap(arr,l,(int) (Math.random()*(r-l+1)+l));int v = arr[l];int j = l;for (int i = l + 1; i <= r; i++) {if (arr[i] < v) {swap(arr, j + 1, i);j++;}}swap(arr, l, j);return j;}雙路快速排序
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2x5kgrqW-1638188775159)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20211129172120570.png)]
比單路快一丟丟
方差小(重復數多)的時候 雙路快排會很快
package sort;import java.util.Arrays; import java.util.Random;public class QuickSort2 {public static void main(String[] args) {//雙路快速排序int[] arr = new int[1000];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void quickSort(int[] arr, int l, int r) {if (l >= r) {return;}int p = partion(arr, l, r);quickSort(arr, l, p - 1);quickSort(arr, p + 1, r);}private static int partion(int[] arr, int l, int r) {swap(arr,l,(int) (Math.random()*(r-l+1)+l));int v = arr[l];int i = l + 1;int j = r;while (true){while (i <= r&&arr[i]<v){i++;}while (j>= l+1&&arr[j]>v){j--;}if (i>j){break;}swap(arr, i, j);i++;j--;}swap(arr, l, j);return j;}private static void swap(int[] arr, int i, int j) {//交換int teme = arr[i];arr[i] = arr[j];arr[j] = teme;} }三路快速排序
將相等的中間值分為中間部分
只有方差小的時候會特別快
package sort;import java.util.Arrays; import java.util.Random;public class QuickSort3 {public static void main(String[] args) {//雙路快速排序int[] arr = new int[10];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr));}public static void quickSort(int[] arr, int l, int r) {if (l >= r) {return;}swap(arr,l,(int) (Math.random()*(r-l+1)+l));int v = arr[l];int lt = l;int gt = r + 1;int i = l + 1;while (i < gt) {if (arr[i] < v) {swap(arr, lt + 1, i);lt++;i++;} else if (arr[i] > v) {swap(arr, i, gt - 1);gt--;} else {i++;}}swap(arr, l, lt);quickSort(arr, l, lt);quickSort(arr, gt, r);}private static void swap(int[] arr, int i, int j) {//交換int teme = arr[i];arr[i] = arr[j];arr[j] = teme;} }計數排序
計數排序不是基于比較的排序算法,其核心至于將輸入的數據轉化為鍵存儲在額外開辟的數組空間中。作為一種線性時間復雜度的排序,計數排序要求輸入的數據必須是有確定范圍的整數
典型的犧牲空間換時間
時間復雜度O(n+m)
空間復雜度 o(n+m)
穩定性 :不穩定
先獲取最大最小值 然后創建區間 最后對應++
然后遍歷添加
package sort;import java.util.Arrays; import java.util.Random;public class CountingSort {public static void main(String[] args) {int[] arr = new int[10000];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}countingSort(arr);System.out.println(Arrays.toString(arr));}private static void countingSort(int[] arr) {int min = arr[0];int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] < min) {min = arr[i];}if (arr[i] > max) {max = arr[i];}}int[] temp = new int[max - min + 1];//對應關系 index = number - min number = index + minfor (int i = 0; i < arr.length; i++) {temp[arr[i] - min]++;}//temp[index] 表示index對應的數字number出現的次數int k = 0;for (int index = 0; index < temp.length; index++) {while (temp[index] != 0) {arr[k] = index + min;k++;temp[index]--;}}} }桶排序
是計數排序的升級版
利用了函數的映射關系,高效與否的關鍵就在于這個映射函數的確定
原理 :假設輸入數據服從均勻分布,將數據分到有限數量的桶里面,每個桶再分別排序,(用其他的排序方法).
package sort;import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.Random;public class BucketSort {public static void main(String[] args) {int[] arr = new int[100];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}bucketSort(arr);System.out.println(Arrays.toString(arr));}private static void bucketSort(int[] arr) {//1.獲取最大最小值int min = arr[0];int max = arr[0];for (int i = 1; i < arr.length; i++) {if (arr[i] < min) {min = arr[i];}if (arr[i] > max) {max = arr[i];}}//2.計算痛的數量int bucketNom=(max-min)/arr.length+1;//3.創建所有的桶ArrayList<Integer>[] bucksts=new ArrayList[bucketNom];for (int i = 0; i <bucksts.length ; i++) {bucksts[i]=new ArrayList<>();}//4.遍歷元素分別進桶for (int i = 0; i <arr.length ; i++) {bucksts[(arr[i]-min)/arr.length].add(arr[i]);}//5.對每一個桶進行排序for (int i = 0; i < bucksts.length; i++) {bucksts[i].sort(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return o1.compareTo(o2);}});}//6.將桶中的數據放入原數組中int index=0;for (int i = 0; i <bucksts.length ; i++) {for (int j = 0; j <bucksts[i].size() ; j++) {arr[index++]=bucksts[i].get(j);}}} }基數排序
基數排序是按照地位先排序,然后收集;再按照高位排序,然后再收集;依次類推,直到最高位。
有時候有些屬性是有優先級順序的,先按低優先級排序,再按高優先級排序。最后的次序就是高優先級的在前,高優先級相同的低優先級在前。
時間復雜度O(n+m)
空間復雜度 o(n+m)
穩定性 :穩定
package sort; import java.util.Arrays; import java.util.LinkedList; import java.util.Random;public class RadixSort {public static void main(String[] args) {int[] arr = new int[100];Random random = new Random();for (int i = 0; i < arr.length; i++) {arr[i] = random.nextInt(10);}radixSort(arr);System.out.println(Arrays.toString(arr));}private static void radixSort(int[] arr) {//1.先找到最大值 決定輪數int max = arr[0];for (int i = 0; i < arr.length; i++) {if (arr[i] > max) {max = arr[i];}}//2.計算位數int radex = (max + "").length();//3.創建桶LinkedList <Integer>[] buckets=new LinkedList[10];for (int i = 0; i < buckets.length; i++) {buckets[i] = new LinkedList<Integer>();}//4.不斷按優先等級如同 個十 百千 萬...for (int r = 0; r <=radex ; r++) {for (int i = 0; i < arr.length; i++) {buckets[getIndex(arr[i],r)].add(arr[i]);}int index=0;for (int i = 0; i <buckets.length ; i++) {while (!buckets[i].isEmpty()){arr[index++]=buckets[i].poll();}}}}private static int getIndex(int num, int r) {int ret =0;for (int i = 0; i <r ; i++) {ret=num%10;num/=10;}return ret;} }總結
- 上一篇: 固态硬盘,机械硬盘,交换内存,虚拟内存,
- 下一篇: 管理经济分析05:并购、价格歧视、四个市