1.順序查找。
按數組的順序從前往後一直比較,直到找到目標值返回。
優點:對數組的結構沒有特定的要求,算法簡單。
缺點:當數組個數n較大時,效率低下。
時間複雜度:最大時間複雜度是O(n),最小時間複雜度是O(1),平均時間複雜度是O(n/2).
<span style="white-space:pre"> </span>/**
* 順序查找算法
*
* @param array
* 數組
* @param target
* 目標
* @return 找到,返回下標值;找不到返回0x80000000
*/
public int sequentialSearch(int[] array, int target) {
if (array == null) {
throw new NullPointerException("the array can't not be null!");
}
if (array.length <= 0) {
throw new IllegalArgumentException("the length of array is illgal!");
}
for (int index = 0; index < array.length - 1; index++) {
if (array[index] == target) {
return index;
}
}
return Integer.MIN_VALUE;
}
2.二分查找:
從數組的中間開始查找,若找到目標值則返回;若目標值比中間數小則遞歸查找前半部分;若目標值比中間數大則遞歸查找後半部分。
優點:比較次數較少,效率比較高
缺點:只適用於不經常變動有序數組
時間複雜度:O(log(n))
/**
* 二分查找算法
* @param array 有序數組
* @param target 目標數值
* @return 找到,返回下標值;找不到返回0x80000000
*/
public int binarySearch(int[] array, int target) {
if (array == null) {
throw new NullPointerException("the array can't not be null!");
}
if (array.length <= 0) {
throw new IllegalArgumentException("the length of array is illgal!");
}
int low = 0;
int high = array.length - 1;
while (low <= high) {
int middle = (low + high) / 2;
if (target == array[middle]) {
return middle;
}
if (target > array[middle]) {
low = middle + 1;
} else {
high = middle - 1;
}
}
return Integer.MIN_VALUE;
}
排序方法:
1.插入排序:
將一個數據插入到已經排好序的有序數據中,在有序序列中選出合適的位置插入,從而得到一個新的、個數加一的有序數據。
優點:是穩定的排序方法。
缺點:算法適用於少量數據的排序
時間複雜度爲O(n^2)。
<span style="white-space:pre"> </span>public int[] insertSort(int[] array) {
if (array == null) {
throw new NullPointerException("the array can't not be null!");
}
if (array.length <= 0) {
throw new IllegalArgumentException("the length of array is illgal!");
}
for (int i = 0; i < array.length - 1; i++) {
int index = halfFindIndex(array, array[i], i);
if (index != i) {
int temp = array[i];
for (int j = i; j > index; j--) {
array[j] = array[j - 1];
}
array[index] = temp;
}
}
return array;
}
private int halfFindIndex(int[] array, int target, int end) {
int low = 0;
int high = end;
int middle = 0;
while (low <= high) {
middle = (low + high) / 2;
if (target < array[middle]) {
low = middle + 1;
} else {
high = middle - 1;
}
}
if (target > array[middle]) {
middle++;
}
return middle;
}
2.冒泡排序
每次將相鄰的兩個數進行比較,如果想升序,則大數往後,反之亦然。
優點:算法簡單,穩定算法
缺點:效率低下的排序方法,在數據規模很小時,可以採用;
時間複雜度:無序O(n^2),有序o(1)
<span style="white-space:pre"> </span>public int[] bubbleSort(int[] array) {
if (array == null) {
throw new NullPointerException("the array can't not be null!");
}
if (array.length <= 0) {
throw new IllegalArgumentException("the length of array is illgal!");
}
int flag = array.length - 1;
while (flag > 0) {
int end = flag;
flag = 0;
for (int i = 0; i < end; i++) {
if (array[i] > array[i + 1]) {
int temp = array[i + 1];
array[i + 1] = array[i];
array[i] = temp;
flag = i;
}
}
}
return array;
}
3.歸併排序
採用分治的思想,通過分割和合並,達到目的
優點:算法簡單,穩定算法
平均時間複雜度:O(nlog2n)
空間複雜度:O(n) (用於存儲有序子序列合併後有序序列)
/**
* 歸併排序
*
* @param unSortArray
* @return
* @throws NullPointerException
* @throws IllegalArgumentException
*/
public int[] mergerSort(int[] unSortArray) throws NullPointerException,
IllegalArgumentException {
if (unSortArray == null) {
throw new NullPointerException("the array is null!");
}
if (unSortArray.length <= 0) {
throw new IllegalArgumentException("the size of array is illgal!");
}
int last = unSortArray.length - 1;
int[] temp = new int[unSortArray.length];
return merger(unSortArray, 0, last, temp);
}
/**
* 遞歸實現歸併排序
*
* @param unSortArray
* 無序數組
* @param first
* 開始下標
* @param last
* 最後有效下標
*/
private int[] merger(int[] unSortArray, int first, int last, int[] temp) {
if (temp == null) {
return null;
}
if (first < last) {
int middle = (first + last) / 2;
// 左邊
merger(unSortArray, first, middle, temp);
// 右邊
merger(unSortArray, middle + 1, last, temp);
// 排序
mergerArray(unSortArray, first, middle, last, temp);
}
return unSortArray;
}
/**
* 將兩個有序序列合併成一個有序序列
*
* @param array
* 一個無序序列
* @param first
* 開始的座標
* @param last
* 最後的座標
* @param temp
* 暫存數組
*/
private void mergerArray(int[] array, int first, int mid, int last,
int[] temp) {
int start = first;
int latterIndex = mid + 1;
int tempIndex = 0;
while (start <= mid && latterIndex <= last) {
// 比較將數放進暫存數組中
if (array[start] < array[latterIndex]) {
temp[tempIndex++] = array[start++];
} else {
temp[tempIndex++] = array[latterIndex++];
}
}
while (start <= mid) {
// 將middle以前的有序序列暫存到數組中
temp[tempIndex++] = array[start++];
}
while (latterIndex <= last) {
// 將middle以後的有序序列暫存到數組中
temp[tempIndex++] = array[latterIndex++];
}
for (int i = 0; i < tempIndex; i++) {
// 將暫存數組裏的數複製到一開始的無序序列中
array[first + i] = temp[i];
}
}
4.快速排序
1.先從數列中取出一個數作爲基準數。
2.分區過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
3.再對左右區間重複第二步,直到各區間只有一個數。
是不穩定的算法
快速排序時間複雜度下界爲O(nlgn),最壞情況爲O(n^2)。在實際應用中,快速排序的平均時間複雜度爲O(nlgn)
只要對快速排序做簡單的操作,就能使時間複雜度總是O(nlgn):
1.對排序數據進行打亂;
2.隨機挑選基準數.
額外空間O(log(n))
<span style="white-space:pre"> </span>public int[] quickSort(int[] unSortArray, int left, int right)
throws NullPointerException, IllegalArgumentException {
if (unSortArray == null) {
throw new NullPointerException("the array is null!");
}
if (unSortArray.length <= 0) {
throw new IllegalArgumentException("the size of array is illgal!");
}
if (left < right) {
int start = left;
int end = right;
// 選第一個爲基準
int x = unSortArray[start];
while (start < end) {
while (start < end && x < unSortArray[end]) {
// 找到小於基準的數
end--;
}
if (start < end) {
// 交換位置
unSortArray[start] = unSortArray[end];
start++;
}
while (start < end && x > unSortArray[start]) {
// 找到大於基準的數
start++;
}
if (start < end) {
// 交換位置
unSortArray[end] = unSortArray[start];
end--;
}
}
unSortArray[start] = x;
quickSort(unSortArray, left, start - 1); // 遞歸調用
quickSort(unSortArray, start + 1, right);
}
return unSortArray;
}