最近身邊的朋友都在聊算法,突然想把幾個大學接觸到的排序算法思路整理一下(大學那會兒只能理解,還沒辦法編程實現)。
- 快速排序算法gim
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
1.設定兩個指針變量(下標爲0,length-1),指向數組左右兩邊,且數組一個值作爲指標(劃分左右的參照)
2.從右邊high指向的值和tmp比較,high小則值複製給low,low向前移一位,且一下次從low位置開始比較,大於等於則high指針向左移一位,繼續比較
3.此時比較low指針和指標的大小,如果low指向值大於指標值(23),將low複製給high指向值,high向左移一位。如果low指向值小於指標值(23),low向右移動一位。直到low=high,將指標值賦給low指向的數組下標。結束一次的排序
4.一次排序過後,會出現以指標值爲基準,左邊小於指標值,右邊大於指標值(左右兩邊爲無序,需要遞歸排序)
實現代碼:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class QuickSort {
public static void main(String[] args) {
int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
System.out.println("begin :nums:" + Arrays.toString(nums));
//第一次排序取整個數組,下標從0到數組最後
nums = quickSort(nums,0 , nums.length - 1);
System.out.println(" end :nums:" + Arrays.toString(nums));
}
/**
* desc:快速排序
* @param nums
* @return
*/
public static int[] quickSort(int[] nums, int low, int high){
//當要排序的數組左下標和又下標重合時,表示長度爲1,不做排序
if(low >= high)
return nums;
int low_ = low , high_ = high;
//將數組第一位作爲臨時變量(即劃分左小又大的對比指標)
int tmp = nums[low];
//控制和指標對比的元素索引方向(low or high)
boolean isLeft = false;
//下標重合時,退出比較
while(low < high){
//數組左邊和指標的大小比較
if(isLeft){
//數組左指針指向的值小於指標值,指針向後移一位,繼續比較
if(nums[low] < tmp){
low ++;
continue;
}else{
//左指針值大於指標值,複製到右指針的位置,然後改變方向從比較指標右邊的值
nums[high--] = nums[low];
isLeft = !isLeft;
continue;
}
}else{//數組右邊和指標的大小比較
//右指針值大於指標值,右指針向左移動一位
if(nums[high] >= tmp){
high --;
continue;
}else{//右指針小於指標值,將右指針值複製給左指針,並改變方向,比較指標左邊部分的值
nums[low] = nums[high];
isLeft = !isLeft;
continue;
}
}
}
//比較完後發現low下標對應的值有重複,將指標值複製給low對應的下標
nums[low] = tmp;
//第一次排序後,以指標爲基準,左小右大(左右部分無序,需要在排序)
//當左邊的數組大於2個數的時候,對左邊進行遞歸排序
if(low > 2){
//對數組的最左邊到指標左邊一位部分進行遞歸排序(指標左邊部分的排序)
quickSort(nums,low_ , low - 1);
}
if(low < nums.length - 2){
//對指標右邊一位到數組最右邊部分進行遞歸排序(指標右邊部分的排序)
quickSort(nums,low + 1,high_);
}
return nums;
}
}
- 選擇排序
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小(大)元素,然後放到已排序序列的末尾。以此類推,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法
1.指針(index)指向數組最左邊,將指針指向元素和index+1元素一次進行比較,如果元素小於指針元素,互換位置(5比31小互換位置)
2.比較比較元素小標右移動(下標+1),和指針(index)繼續比較,小於指針元素的互換位置,一輪比較之後,會出現一個最小值爲指針指向值,指針右移一位(index+1),進入下一輪指針和其右邊的數組大小比較。
3.當指針執行數組最後一個元素時,排序結束
代碼實現:
package com.lirong.sort;
import java.util.Arrays;
/**
* desc:SelectionSort
* author:lirong
* data:2019/05/09
*/
public class SelectionSort {
public static void main(String[] args) {
int[] nums = {12,34,34,4554,76,7688,45,34,234,232,342,3,23,12,1223,324,432,2};
System.out.println("begin:" + Arrays.toString(nums));
selectionSort(nums);
System.out.println("end:" + Arrays.toString(nums));
}
/**
* desc:選擇排序
* @return
*/
public static int[] selectionSort(int[] nums){
//指針第一次指向數組最左邊邊元素
int index = 0, tmp ;
//當指針移動到數組最右邊,排序結束
while(index < nums.length - 1){
//遍歷指針右邊的元素,比指針指向的元素小的,互換位置,每次遍歷完,指針向左移一位
for(int i = index + 1 ; i < nums.length ; i++){
if(nums[index] > nums[i]){
tmp = nums[i];
nums[i] = nums[index];
nums[index] = tmp;
}
}
//每次遍歷之後,會出現一個最小的元素
index ++;
}
return nums;
}
}
三、冒泡排序
它重複地走訪過要排序的元素列,依次比較兩個相鄰的元素,如果他們的順序(如從大到小、首字母從A到Z)錯誤就把他們交換過來。走訪元素的工作是重複地進行直到沒有相鄰元素需要交換,也就是說該元素列已經排序完成
- 指針指向數組最後一個元素,讓其與前一個元素比較。如果前一個元素大於指針元素,則交換位置。否則指針向前移一位(3比8小,不做交換)
- 指針向前移一位,繼續做比較(71比3大,互換位置)
- 以此比較下去,最後出現在數組最左邊會是一個最小的元素(如圖)
- 進入第二輪比較,指針仍舊從最末尾開始比較(此時比較到左邊第二個元素時停止(因爲最左邊元素(既下標爲0的元素) 已經是數組中最小的,不需要比較了))。
Ps:當從右到左一輪比較下來,都沒有發生過數據交換,說明數組已經是有序的,直接推出排序即可.
插入排序
思想:將索引指向的值與前面已經有序的值進行比較(從最右邊,最大的值開始)。如果該值比索引值大,將他賦值給他後一位值,對比值向左移一位。直到對比的值小於索引值,將索引值賦值給對比值的上一位(上一位已經賦值給了他的再上一位)。
示例:
1,。索引剛開始指向下標爲1的,從索引左邊數組最右邊(下標設爲j)開始比較(第一次左邊數組只有一個元素,將索引值(3)存入tmp)==如果對比值大,對比值賦值給他的後一位。然後對比值下標減一(第一次j=0,減一後爲-1,結束循環)。然後將tmp的值賦給j+1
- 此時數組如圖2.索引右移一位,指向2,開始新一輪的比較(此時j=1,如圖3).比較索引值tmp(2)和j=1的值(7),對比值大,將對比值賦值給他後一位,如圖4。
- 對比值下標減一,繼續比較(3>tmp=2),將對比值(3)賦值給他後一位,如圖5.
- 對比值下標減一(此時j--=-1<0),結束循環.
- 最後將tmp賦值給j++=0
- 一輪插入結束,索引值向右移一位,繼續比較
代碼實現:
package com.lirong.sort;
import java.util.Arrays;
/**
* author:lirong
* data:2019/5/14
* desc:insertion soort
*/
public class InsertionSort {
public static void main(String[] args) {
int[] nums = {55,34,45,76,87,45,23,23,45,3,23,2,2,2,34,56,7,8,90,54,3,98,4,2,223,5,54,223};
System.out.println("begin :nums:" + Arrays.toString(nums));
//第一次排序取整個數組,下標從0到數組最後
nums = insertionSort(nums);
System.out.println(" end :nums:" + Arrays.toString(nums));
}
/**
* desc:插入排序
* @param nums
* @return
*/
public static int[] insertionSort(int[] nums){
for(int index = 1 ; index < nums.length ; index++){
//保存索引值
int tmp = nums[index];
//比較值從索引值左邊第一個開始
int j = index - 1;
for(; j >= 0; j--){
//當比較值大於索引值,將比較值賦值給比較值後一直
if(nums[j] > tmp){
nums[j+1] = nums[j];
}else{//當檢索到比索引值小的元素的時候,將索引值放到比較值後一位(即j+1的位置)
break;
}
}
nums[j + 1] = tmp;
}
return nums;
}
}