1.冒泡排序
1.1 實現思路
冒泡排序思想是通過將兩個互相相鄰的元素進行比較,如果前一個元素大於後一個元素,進行交換位置。否則不交換。外層循環控制層數,內存循環控制個數。每進行一輪都會將最大數字移動到最後,所以經過多次交換就可以實現將數組中的元素進行有序排列了。
note:我們在內存循環中加入一個判斷標誌 如果當前內存循環沒有進行交換數據的操作 說明這個數組的元素已經是有序的 就可以退出循環操作。
1.2 代碼實現
public static void bubbleSort(int [] arr){
for (int i = 0; i < arr.length-1; i++) {
boolean flag = true;
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;
flag = false;
}
}
if (flag){
break;
}
}
}
2.選擇排序
2.1 實現思路:
選擇排序主要每次選擇一個最小的下標值,在內層循環中找到最小值下標,循環n次找到最小值。最後將預先尋找的值與最小下標值進行交換,每次選擇一個最小的。多次循環就可以將一個無序的數組轉換成一個有序的數組了。
2.2 代碼實現
public static void selectSort2(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
3.插入排序
3.1 實現思路:
插入排序的思想是 將數組中分爲已排好序 和
未拍好序兩部分。第一個是已經拍好序的。所以i從1開始每次選擇一個元素,插入到已排好序當中。而內層循環所作的就是找到判斷當前要插入的元素應該插入的位置。如此反覆執行,就可以找到應當插入的位置。
3.2 代碼實現
public static void selectSort2(int [] arr){
for (int i = 1; i < arr.length; i++) {
int value = arr[i];
int j = i-1;
for (; j >=0 ; j--) {
if (arr[j]>value){
arr[j+1] = arr[j];//care
}else {
break;
}
}
arr[j+1] = value;//care
}
}
4.歸併排序
4.1 實現思路
歸併排序:使用遞歸思想,將一個無序的數組多次分割成多個小的數組,將小的數組進行元素比較 最小的元素放在前面,反覆執行就可以實現數組排序了
4.2 代碼實現
public static void mergeSorts(int[] arr) {
mergesort(arr, 0, arr.length - 1);
}
private static void mergesort(int[] arr, int p, int r) {
if (p >= r) return;
int q = p + (r - p) / 2;
//合併左邊
mergesort(arr, p, q);
//合併右邊
mergesort(arr, q + 1, r);
merge(arr, p, q, r);
}
private static void merge(int[] arr, int p, int q, int r) {
int i = p;
int j = q + 1;
int count = 0;
//定義一個數組
int[] tmp = new int[r - p + 1];
//合併兩個數組
while (i <=q && j<=r) {
if (arr[i] < arr[j]) {
tmp[count++] = arr[i++];
} else {
tmp[count++] = arr[j++];
}
}
int start = i;
int end = q;
if (j <= r) {//注意邊界條件
start = j;
end = r;
}
//轉移剩餘的元素
while (start <= end) {
tmp[count++] = arr[start++];
}
//迴歸arr
for (int k = 0; k <= (r - p); k++) {
arr[p+k] = tmp[k];
}
}
4.3 簡潔版
private static void mergeSort(int[] array, int left, int right) {
//條件判斷
if (right <= left) {
return;
}
//中間下標位置
int mid = (left + right) >> 1;
//左邊排序
mergeSort(array, left, mid);
//右邊排序
mergeSort(array, mid + 1, right);
//合併
merge(array, left, mid, right);
}
private static void merge(int[] array, int left, int mid, int right) {
//臨時數組
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, p = 0;
//比較大小 後存儲
while (i <= mid && j <= right) {
temp[p++] = array[i] <= array[j] ? array[i++] : array[j++];
}
//剩餘的存儲
while (i <= mid) {
temp[p++] = array[i++];
}
while (j <= right) {
temp[p++] = array[j++];
}
//賦值給原來的數組
for (int k = 0; k < temp.length; k++) {
array[left + k] = temp[k]; //care
}
}
5.快速排序
5.1 實現思路
如果要在排序數組中下標從p到r之間的一組數據,我們選擇p到r之間的任意一個數據作爲一個piovt(分區點),我們遍歷p到r之間的數據,將小於piovt的放到左邊,將大於piovt的放到右邊,將piovt放到中間,經過這一步驟之後,數組p到r之間的數據就被分成了三部分,前面是p到q-1之間是小於piovt,中間是piovt
後面的q+1到r之間的是大於piovt。
5.2 代碼實現
private static void quickSort(int[] arr, int start, int end) {
if(end <= start){
return;
}
int piovt = partition(arr,start,end);//獲取到piovt下標
quickSort(arr,start,piovt-1);
quickSort(arr,piovt+1,end);
}
private static int partition(int[] arr, int start, int end) {
//piovt 標杆位置, counter 小於piovt的元素的個數
int piovt = end;
int counter = start;
for (int i = start; i < end; i++) {
if (arr[i]<arr[piovt]){ //如果小於Arr[piovt] 移動到piovt前面 否則不動
int temp = arr[counter];
arr[counter] = arr[i];
arr[i] = temp;
counter++;
}
}
int temp = arr[piovt];
arr[piovt] = arr[counter];
arr[counter] = temp;
return counter;
}