6種排序演算法java實現
阿新 • • 發佈:2018-12-12
6種排序演算法
- 氣泡排序
- 選擇排序
- 插入排序
- 計數排序
- 快速排序
- 歸併排序
1)氣泡排序
相鄰的兩個數字比較排序,先將最大的交換到最後面,然後重複。
程式碼實現
2)選擇排序
從第一個位置開始,用某個位置依次與後邊所有元素比較一遍,如果後面的某個位置的數比該位置的數小,就換一換位置。
3)插入排序
某個位置與前邊所有元素比較, 這個位置的元素比前邊元素小, 那麼把這個位置的元素插入到比它大的那個元素的位置。
4)計數排序
Hbase 布隆過濾器 計數排序
利用陣列的下標進行排序(要求理解原理)
程式碼實現
public class JiShuPaiXu { public static void main(String[] args) { int[] arr = {2,1,4,7,2,8,1,5,1}; jisupaicu(arr); } public static void jisupaicu(int[] arr){ int max = arr[0]; for(int i =1;i<arr.length;i++){ if(arr[i]>max){ max=arr[i]; } } int[] newArr = new int[max+1]; for(int i = 0;i<arr.length;i++){ newArr[arr[i]]++; } for(int i = 0;i<newArr.length;i++){ for(int j=0;j<newArr[i];j++){ System.out.print(i+" "); } } } }
5)快速排序
時間複雜度nlogn
1、原理:
對陣列排序
先選取一個基準點,作用:基準點左側小於基準點的資料,基準點右側大於基準點的資料
基準點:最常用的基準點選第一個
一個大陣列不停的進行拆分 拆分的最終結果每個陣列只有一個元素
程式碼實現
public class QuickSort { public static void main(String[] args) { int[] arr={1,34,2,5,6,7,8,9,0,10,2,3,4,5}; sort(arr,0,arr.length-1); System.out.println(Arrays.toString(arr)); } //引數 //出口 /** * * @param arr * @param left 左側的元素下標位置 * @param right 右側元素的下標 * 執行的條件 left<right */ public static void sort(int[] arr,int left,int right){ if(left>right){ return; } //符合遞迴的邏輯的 //拆分 大陣列 按照我們的規則拆分 //關鍵找基準點 int point=getIndexPoint(arr,left,right); //進行遞歸回調 //先對左側陣列進行回撥 sort(arr,left,point-1); //對右側的陣列進行回撥 sort(arr,point+1,right); } //為每一個數組找基準點 private static int getIndexPoint(int[] arr, int left, int right) { //指定初始的基準點 int key=arr[left]; while(left<right){ //從右向左迴圈 while(arr[right]>=key&&left<right){ right--; } //右側的資料小於基準點 arr[left]=arr[right]; //從左向右進行遍歷 while(arr[left]<=key&&left<right){ left++; } arr[right]=arr[left]; } arr[left]=key; return left; } }
6)歸併排序:
時間複雜度nlogn
2路歸併排序
做的是兩個有序集合的排序
便於理解 拿兩個有序的陣列進行排序
前提:兩個資料集都是已經排好序的。只有一個數據集。這個資料集是排好序的
對一個大的資料集進行排序 將大的資料集分成多個小的資料集 這裡的多個小的資料集是排好序的
歸併排序進行拆分的時候 拆分的小資料集每個資料集中只有一個元素
歸:拆分的過程
並:將兩兩個資料集進行匯籠排序。Merge(檔案歸併)
程式碼實現:
public class MergeSort01 {
public static void sort(int[] arr1,int[] arr2){
//記錄兩個陣列的下標變化
int m=0;
int n=0;
int index=0;
//兩個變數記錄最大的下標
int x=arr1.length-1;
int y=arr2.length-1;
//建立一個新的陣列 作用:盛放最終的結果
int[] newarr=new int[arr1.length+arr2.length];
//迴圈遍歷比較 while迴圈不能確定迴圈次數
while(m<=x && n<=y){
if(arr1[m]<arr2[n]){
newarr[index++]=arr1[m++];
}else{
//arr1[m]>=arr2[n]
newarr[index++]=arr2[n++];
}
}
while(m<=x){
newarr[index++]=arr1[m++];
}
while(n<=y){
newarr[index++]=arr2[n++];
}
for(int i:newarr){
System.out.print(i+" ");
}
}
public static void main(String[] args) {
int[] arr1={1,2,4,6,7};
int[] arr2={2,3,5,7,8,9,12,14};
sort(arr1, arr2);
}
}
例項一:歸併排序
public class MergeSortFinal {
public static void main(String[] args) {
int[] arr={3,1,2,5,7,5,3,8,7,6,4,8,9,34,56,78,23,12,11};
int[] newarr=new int[arr.length];
chai(arr,0,arr.length-1,newarr);
System.out.println(Arrays.toString(arr));
}
//拆分 遞迴
public static void chai(int[] arr,int left,int right,int[] newarr){
if(left>=right){
return;
}else{
int mid=(left+right)/2; //計算中間值
//遞迴呼叫
//左半部分
chai(arr, left, mid,newarr);//邊界
chai(arr,mid+1,right,newarr);//這句程式碼執行完,整個拆的過程完成
//並
mergeResult(arr, left, right, mid, newarr);
}
}
//並 merge檔案歸併
public static void mergeResult(int[] arr,int left,int right,int mid,int[] newarr){
//定義;兩個變數 記錄資料集的左側的邊界
int m=left;
int n=mid+1;
//定義兩個變數 記錄每個資料集的右側的邊界
int x=mid;
int y=right;
//定義一個變數 記錄新陣列的下標的
int index=0;
while(m<=x&&n<=y){
if(arr[m]<arr[n]){
newarr[index++]=arr[m++];
}else{//arr[left]>=arr[mid+1]
newarr[index++]=arr[n++];;
}
}
while(m<=x){
newarr[index++]=arr[m++];
}
while(n<=y){
newarr[index++]=arr[n++];
}
for(int i=0;i<index;i++){
arr[i+left]=newarr[i];
}
}
}