冒泡排序
/*
* 冒泡排序
*
* 每一趟出來一個最大的數(冒出一個泡泡)
*
* */
public class BubbleSort {
public static void bubbleSort(int []arr){
//首先對輸入做判斷
if(arr==null||arr.length<2){
return;
}
for(int i=0;i<arr.length-1;i++){ //一共n-1躺排序(n個數需要n-1躺排序) 每一趟冒出來一個最大的數
for(int j=0;j<arr.length-1-i;j++){
//每過一趟排序,j的遍歷範圍縮減1 (最右邊的坑已經被最大的數給佔了,現在第二大的數準備入從右往左
//數的第二個坑...)
if(arr[j]>arr[j+1]){
MySwap(arr,j,j+1);
}
}
}
}
public static void MySwap(int []arr ,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String []args){
int []arr={2,0,4,8,9,1,2,7};
bubbleSort(arr);
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
}
時間複雜度: O(n^2)
空間複雜度: O(1)
選擇排序
/*
* 選擇排序 每次都選擇一個最小的
* */
public class SelectSort {
public static void selectSort(int []arr){
for(int i=0;i<arr.length;i++){ //i來控制遍歷的範圍 在該範圍下選擇一個最小的數
int minIndex=i;
for (int j = i+1; j < arr.length; j++) { //找出一個最小的數放在minInde的位置上
if(arr[j]<arr[minIndex]){
MySwap(arr,minIndex,j); //這樣寫是有問題的
}
}
}
}
//優化版 遍歷完所有數,確定minindex 在Swap
public static void selectSort_edition2(int []arr){
for(int i=0;i<arr.length;i++){ //i來控制遍歷的範圍 在該範圍下選擇一個最小的數
int minIndex=i;
for (int j = i+1; j < arr.length; j++) { //找出一個最小的數放在minIndex的位置上
if(arr[j]<arr[minIndex]){
minIndex=j;
}
}
MySwap(arr,i,minIndex); //確定一個最小的只交換一次
}
}
public static void MySwap(int []arr ,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String []args){
int []arr={2,0,42,8,9,11,2,7};
selectSort_edition2(arr);
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
}
時間複雜度: O(n^2)
插入排序
鬥地主
類似你手裏的牌是已經排好序的,你新起一張牌,這張牌與你手裏的最大的一張牌比較,如果大,就放你右邊,如果小,就和手裏最大的牌之前的一張牌比較...
根據當前的大小能比較到哪個位置,插入
/*
插入排序
* */
public class InsertSort {
public static void insertSort(int []arr){
for (int i = 1; i < arr.length; i++) { //考慮的當前數i 往前面有序區插入(0 到 i-1)
for (int j = i-1; j >=0 ; j--) { //位置i的前一個數
if(arr[j]>arr[j+1]){
MySwap(arr,j,j+1);
}
}
}
}
//添加標記
public static void insertSort_edition2(int []arr){
boolean isSwaped =false; //i和i-1是否交換了 如果沒有交換直接break
for (int i = 1; i < arr.length; i++) { //考慮的當前數i 往前面有序區插入(0 到 i-1)
for (int j = i-1; j >=0 ; j--) { //位置i的前一個數
if(arr[j]>arr[j+1]){
MySwap(arr,j,j+1);
isSwaped=true;
}
if(!isSwaped){
break;
}
}
}
}
public static void MySwap(int []arr ,int i,int j){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String []args){
int []arr={2,0,42,8,9,11,2,7};
insertSort_edition2(arr);
for (int i = 0; i <arr.length ; i++) {
System.out.println(arr[i]);
}
}
}
注意:選擇排序和冒泡排序跟數據狀況是沒有關係的 嚴格的 O(n^2)
插入排序的好壞要根據數據狀況決定的
如果已經排好序了,插入排序O(n)
如果是逆序,插入排序O(n^2)
於是有了最好情況,最差情況
這樣的算法按照最差的情況估計算法複雜度,因此插入排序就是O(n^2)