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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

常见排序查询算法Java代码实现

發布時間:2023/12/10 java 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常见排序查询算法Java代码实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 排序算法代碼實現

/*** ascending sort* 外層循環邊界條件:總共需要冒泡的輪數--每一輪都將最大或最小的數冒泡到最后* 內層循環邊界條件:冒泡數字移動的邊界--最終數字需冒泡到此處* 時間復雜度:O(n^2)* @param arr*/ public static void bubbleSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}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]) {int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}} }/*** 每次都將未排序數組中的最大或最小元素找出來和第一個元素交換位置* 時間復雜度:O(n^2)* @param arr*/ public static void selectSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}for(int i = 0; i < arr.length - 1; i++) {//尋找最小元素的下標,避免頻繁交換數組int min = i;for(int j = i + 1; j < arr.length; j++) {if (arr[j] < arr[min]) {min = j;}}//將最小的元素交換到未排序數組的最前面int temp = arr[i];arr[i] = arr[min];arr[min] = temp;} }/*** 插入排序:順次從數組中選擇一個數,插入到前面已排序的數組中* 時間復雜度:O(n)~O(n^2)* @param arr*/ public static void insertSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}for(int i = 1; i < arr.length; i++) {int value = arr[i];//插入的位置int j = 0;//循環i前面的數,若值比插入的值大,則順次向后移動for (j = i - 1; j >= 0; j--) {if(arr[j] > value) {arr[j+1] = arr[j];} else {break;}}arr[j+1]=value;} }/*** 希爾排序:插入排序的改進版,也稱縮小增量排序** @param arr*/ public static void shellSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int length = arr.length;//區間int gap = 1;while(gap < length) {gap = gap * 3 +1;}while(gap > 0) {for(int i = gap; i < length; i++) {int tmp = arr[i];int j = i -gap;//跨區間排序while(j >= 0 && arr[j] > tmp) {arr[j+gap] = arr[j];j -= gap;}arr[j + gap] = tmp;}gap = gap / 3;} }/*** 歸并排序--核心為分治法* 時間復雜度O(nlogn)* @param arr*/ public static void mergeSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int[] tmpArr = new int[arr.length];mSort(arr,tmpArr, 0, arr.length - 1); }private static void mSort(int[] arr, int[] tmpArr, int startIndex, int endIndex) {//邊界條件:數組已不可再拆if (endIndex <= startIndex) {return;}//將數組對拆為前后兩個數組int middleIndex = startIndex + (endIndex - startIndex)/2;mSort(arr, tmpArr, startIndex, middleIndex);mSort(arr, tmpArr, middleIndex + 1, endIndex);merge(arr, tmpArr, startIndex, middleIndex, endIndex); }private static void merge(int[] arr, int[] tmpArr, int startIndex, int middleIndex, int endIndex) {//將要合并的數組復制到臨時數組for (int i = startIndex; i <= endIndex; i++) {tmpArr[i] = arr[i];}//左邊數組起始下標int left = startIndex;//右邊數組起始下標int right = middleIndex + 1;for(int k = startIndex; k <= endIndex; k++) { if (left > middleIndex) {arr[k] = tmpArr[right++];} else if (right > endIndex) {arr[k] = tmpArr[left++];} else if (tmpArr[left] < tmpArr[right]) {arr[k] = tmpArr[left++];} else {arr[k] = tmpArr[right++];} } }/*** 快速排序:隨機選取一個參考值,將比參考值小的數移到數組前段,大的值移到后段* 以參考值為臨界點遞歸拆分數組直至數組不能拆分,此時數組本身已排好序* 快速排序時間復雜度為O(nlogn),對于逆序數組復雜度退化為O(n^2),為了避免極端情況,可隨機選取參考值* @param arr*/ public static void quickSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}qSort(arr , 0, arr.length - 1); }private static void qSort(int[] arr, int startIndex, int endIndex) {// 設置邊界條件if (endIndex <= startIndex) {return;}// 將數組按參考值整理成比參考值小的前段和比參考值大的后段,返回參考值的位置int refIndex = partition(arr, startIndex, endIndex);// 參考值已確定排序后的位置,不參與數組拆分if (refIndex > startIndex) {qSort(arr, startIndex, refIndex - 1);}if (endIndex > refIndex) {qSort(arr, refIndex + 1, endIndex);} }
private static int partition(int[] arr, int startIndex, int endIndex) {// 將數組中refValue的值與最后一個數交換,隨機選取參考值可避免時間復雜度退化為O(n^2)int refIndex = startIndex + new Random().nextInt(endIndex - startIndex + 1);// 深坑,當兩個數指向同一個時,會影響異或結果if (refIndex != endIndex) {arr[endIndex] = arr[endIndex] ^ arr[refIndex];arr[refIndex] = arr[endIndex] ^ arr[refIndex];arr[endIndex] = arr[endIndex] ^ arr[refIndex];}// 分組下標int partitionIndex = startIndex - 1;// 數組最后一個值為參考值,不參與循環for (int dataIndex = startIndex; dataIndex < endIndex; dataIndex++) {// 與參考值進行比較,若比參考值小,則移動到數組前面if ((arr[dataIndex] < arr[endIndex]) ) {// 始終指向最后一個確定比參考值小的值++partitionIndex;// 如果當前數據的位置與參考下標不一致,將此值與參考下標指向的值交換,保證小的值交換到前面if (partitionIndex != dataIndex) {arr[dataIndex] = arr[dataIndex] ^ arr[partitionIndex] ;arr[partitionIndex] = arr[dataIndex] ^ arr[partitionIndex];arr[dataIndex] = arr[dataIndex] ^ arr[partitionIndex];} }}// 將參考值交換到指定位置++partitionIndex;if (partitionIndex != endIndex) {arr[endIndex] = arr[endIndex] ^ arr[partitionIndex] ;arr[partitionIndex] = arr[endIndex] ^ arr[partitionIndex];arr[endIndex] = arr[endIndex] ^ arr[partitionIndex];}return partitionIndex; }/*** 堆排序--最大堆實現* 時間復雜度O(nlogn)* @param arr*/ public static void heapSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int length = arr.length;//構建堆buildHeap(arr, length);for (int i = length - 1; i > 0; i--) {//將堆元素與末位元素調換int temp = arr[0];arr[0] =arr[i];arr[i] = temp;//數組長度-1 隱藏堆尾元素length--;//將堆頂元素下沉,目的是將最大的元素浮到堆頂來sink(arr, 0, length);} }
private static void buildHeap(int[] arr, int length) {for (int i = length / 2; i >= 0; i--) {sink(arr, i , length);} }private static void sink(int[] arr, int index, int length) {//左子節點下標int leftChild = 2 * index + 1;//右子節點下標int rigthChild = 2 * index + 2;//要調整的節點下標int present = index;//下沉左邊if (leftChild < length && arr[leftChild] > arr[present]) {present = leftChild;}//下沉右邊if (rigthChild < length && arr[rigthChild] > arr[present]) {present = rigthChild;}//如果下標不相等,證明調換過了if (present != index) {//交換值int temp = arr[index];arr[index] = arr[present];arr[present] = temp;//繼續下沉sink(arr, present, length);} }/*** 計數排序--時間復雜度為O(n+m),空間大小取決于數組值,時間復雜度為O(n)* 問題點:數組中不能有負數,否則會拋出越界異常* @param arr*/ public static void countSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}//找出數組中的最大值int max = arr[0];for(int i = 1; i < arr.length; i++) {if (arr[i] < 0) {throw new RuntimeException("Cannot use countsort! Array contains negative number.");}if (max < arr[i]) {max = arr[i];}}//利用最大值構建一個數組,用空間換時間int[] countArr = new int[max + 1];//計數for (int i = 0; i < arr.length; i++) {countArr[arr[i]]++;}int index = 0;for (int i = 0; i < countArr.length; i++) {while (countArr[i] > 0) {arr[index++] = i;countArr[i]--;}} }/*** 桶排序--類似于Hash分桶策略* 良好的分桶策略可實現O(n)時間復雜度* @param arr*/ public static void bucketSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}//最大最小值int max = arr[0];int min = arr[0];int length = arr.length;for (int i = 1; i < length; i++) {if (arr[i] > max) {max = arr[i];} else if (arr[i] < min) {min = arr[i];}}//最大值與最小值的差int diff = max - min;//桶列表ArrayList<ArrayList<Integer>> bucketList = new ArrayList<>();for (int i = 0; i < length; i++) {bucketList.add(new ArrayList<>());}//每個桶的存數區間float section = (float)diff / (float)(length -1);//數據入桶for (int i = 0; i < length; i++) {//當前數除以區間得出存放桶的位置 減1后得出桶的下標int num = (int) (arr[i] / section) - 1;if (num < 0) {num = 0;}bucketList.get(num).add(arr[i]);}//桶內排序for (int i = 0; i < bucketList.size(); i++) {Collections.sort(bucketList.get(i));}//寫入數據int index = 0;for (ArrayList<Integer> arrayList: bucketList) {for (int value : arrayList) {arr[index] = value;index++;}} }/*** 基數排序* @param arr*/ public static void radixSort(int[] arr) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int length = arr.length;//最大值int max = arr[0];for(int i = 0;i < length;i++){if(arr[i] > max){max = arr[i];}}//當前排序位置int location = 1;//桶列表ArrayList<ArrayList<Integer>> bucketList = new ArrayList<>();//長度為10 裝入余數0-9的數據for(int i = 0; i < 10; i++){bucketList.add(new ArrayList<>());}while(true){//判斷是否排完int dd = (int)Math.pow(10, (location - 1));if(max < dd){break;}//數據入桶for(int i = 0; i < length; i++){//計算余數 放入相應的桶int number = ((arr[i] / dd) % 10);bucketList.get(number).add(arr[i]);}//寫回數組int nn = 0;for (int i=0;i<10;i++){int size = bucketList.get(i).size();for(int ii = 0;ii < size;ii ++){arr[nn++] = bucketList.get(i).get(ii);}bucketList.get(i).clear();}location++;} }

  2. 查詢算法代碼實現

/*** 順序查找,即為遍歷數組,時間復雜度為O(n)* @param arr* @param value* @return*/ public static int sequentialSearch(int[] arr, int value) {if (arr == null) {throw new RuntimeException("Input arr is null!");}for (int i = 0; i < arr.length; i++) {if (arr[i] == value) {return i;}}return -1; }/*** 二分查找針對以升序排列的數組進行,每次取數組的中間值進行查找* 時間復雜度為O(logn)* @param arr* @param value* @return*/ public static int binarySearch(int[] arr, int value) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int low = 0;int high = arr.length - 1;int mid = 0;while (low <= high) {mid = (low + high)/2;if (arr[mid] == value) {return mid;} else if (arr[mid] > value) {high = mid -1;} else {low = mid + 1;}}return -1; }/*** 二分查找--遞歸實現* @param arr 待查詢數組* @param value 查找目標值* @param low 數組起始下標* @param high 數組結束下標* @return 目標值的下標*/ public static int binarySearchByRecursion(int[] arr, int value, int low, int high) {if (arr == null) {throw new RuntimeException("Input arr is null!");}int mid = low + (high -low)/2;if (low == high && arr[mid] != value) {return -1;}if (arr[mid] == value) {return mid;} else if (arr[mid] > value) {return binarySearchByRecursion(arr, value, low, mid - 1);} else {return binarySearchByRecursion(arr, value, mid + 1, high);} }/*** 插值查找--遞歸實現,原理與二分查找類似,按目標值的大小計算在數組中的權重,適用于均有有序的數組* @param arr 待查詢數組* @param value 查找目標值* @param low 數組起始下標* @param high 數組結束下標* @return 目標值的下標*/ public static int insertionSearch(int[] arr, int value, int low, int high) {if (arr == null) {throw new RuntimeException("Input arr is null!");}// 按目標值與最小值的差估算插值下標的位置int mid = low + ((value - arr[low]) / (arr[high] - arr[low])) * (high -low);if (low == high && arr[mid] != value) {return -1;}if (arr[mid] == value) {return mid;} else if (arr[mid] > value) {return binarySearchByRecursion(arr, value, low, mid - 1);} else {return binarySearchByRecursion(arr, value, mid + 1, high);} }

?

轉載于:https://www.cnblogs.com/beichenroot/p/11122212.html

總結

以上是生活随笔為你收集整理的常见排序查询算法Java代码实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。