java常用算法


java常用排序,程序員必會的排序問題:http://www.cnblogs.com/qqzy168/archive/2013/08/03/3219201.html

 

 

Java實現面試常考的算法

我自己總結了幾個平時面試問得一些算法題, 都是非常非常基礎的問題.

查找算法

典型的二分查找 
對於二分查找算法要求, 查找前的數據必須是已經排好序的, 然后得到數組的開始位置start和結束位置end, 取中間位置mid的數據a[mid]跟待查找數據key進行比較, 若 a[mid] > key, 則取end = mid - 1; 若 a[mid] < key, 則取start = mid + 1; 若 a[mid] = key 則直接返回當前mid為查找到的位置. 依次遍歷直到找到數據或者最終沒有該條數據. 啰嗦這么多, 上代碼!!!

//已經排好序的數組 public static int binarySearch(int[] nums, int key) { int start = 0; int end = nums.length - 1; int mid = -1; while (start <= end) { mid = (start + end) / 2; if (nums[mid] == key) { return mid;//已經查到返回! } else if (nums[mid] > key) { end = mid - 1; } else if (nums[mid] < key) { start = mid + 1; } } return -1; }

 

排序算法

排序算法可以說是老生常談的問題, 下面的代碼思路是根據 嚴蔚敏的《數據結構》而來. 
務必注意: 以下所有的排序算法都是從1開始, 而不是從0開始, 有的排序算法會把0位置當作監視哨 
今天就介紹一下幾種常見的排序算法:

排序之前先寫一個交換方法后面會用到

  //交換 private static void swap(int[] a, int i, int j) { a[i] ^= a[j]; a[j] ^= a[i]; a[i] ^= a[j]; }

 

選擇排序

選擇排序的基本思想是對待排序的記錄序列進行n-1遍的處理,第i遍處理是將L[i..n]中最小者與L[i]交換位置。這樣,經過i遍處理之后,前i個記錄的位置已經是正確的了。

不穩定, 時間復雜度 O(n^2)

//選擇排序 public static void selectSort(int[] a) { for (int i = 1; i < a.length; i++) { int j = selectMinKey(a, i); //從i開始a.length中找到最小的位置 if (i != j) { swap(a, i, j); } } } // 查找從i開始到a.length中最小的位置 private static int selectMinKey(int[] a, int i) { int key = i; for (int j = i + 1; j < a.length; j++) { if (a[j] < a[key]) { key = j; } } return key; } 

 

冒泡排序

冒泡排序方法是最簡單的排序方法。這種方法的基本思想是,將待排序的元素看作是豎着排列的“氣泡”,較小的元素比較輕,從而要往上浮。在冒泡排序算法中我們要對這個“氣泡”序列處理若干遍。所謂一遍處理,就是自底向上檢查一遍這個序列,並時刻注意兩個相鄰的元素的順序是否正確。如果發現兩個相鄰元素的順序不對,即“輕”的元素在下面,就交換它們的位置。顯然,處理一遍之后,“最輕”的元素就浮到了最高位置;處理二遍之后,“次輕”的元素就浮到了次高位置。在作第二遍處理時,由於最高位置上的元素已是“最輕”元素,所以不必檢查。一般地,第i遍處理時,不必檢查第i高位置以上的元素,因為經過前面i-1遍的處理,它們已正確地排好序。

穩定,時間復雜度 O(n^2)

 //冒泡排序 public static void bubbleSort(int[] a) { int len = a.length; for (int i = 1; i < len - 1; i++) { for (int j = i; j < len - i; j++) { if (a[j + 1] < a[j]) { swap(a, j + 1, j); } } } }

 

快速排序

不穩定,時間復雜度 最理想 O(nlogn) 最差時間O(n^2)

快速排序是對冒泡排序的一種本質改進。它的基本思想是通過一趟掃描后,使得排序序列的長度能大幅度地減少。在冒泡排序中,一次掃描只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃描,就能確保某個數(以它為基准點吧)的左邊各數都比它小,右邊各數都比它大。然后又用同樣的方法處理它左右兩邊的數,直到基准點的左右只有一個元素為止。

  //快速排序 public static void quickSort(int[] a, int low, int high) { //遞歸快速排序 int pivotLoc = 0;//中心點 if (low < high) { pivotLoc = partitionLoc(a, low, high); quickSort(a, low, pivotLoc-1); quickSort(a, pivotLoc+1, high); } } //獲取到a的下標 low ~ high 中, a[low]的應該放的位置, 即左邊的數 < a[low] 右邊的數 > a[low] private static int partitionLoc(int[] a, int low, int high) { a[0] = a[low]; while (low < high) { while (low < high && a[high] >= a[0]) { high--; } a[low] = a[high]; while (low < high && a[low] <= a[0]) { low++; } a[high] = a[low]; } a[low] = a[0]; return low; }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM