排序算法

參考:https://blog.csdn.net/weixin_40205234/article/details/86699088

https://blog.csdn.net/adusts/article/details/80882649

從執行效率:冒泡排序<選擇排序<插入排序<快速排序。

從穩點性: 快速排序,選擇排序 不穩定;   冒泡排序,插入排序 穩定。

1. 冒泡排序

以升序爲例,兩個相鄰的數比較大小,如果前面的數比後面的數大,那麼交換位置。雙重for循環,外層循環控制輪數,內層循環控制每輪比較的次數,每輪比較會將該輪最大數交換到最後面。

代碼:

public class BubbleSort {
	public static void main(String[] args) {
		 int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		 BubbleSort(arr);
		 System.out.println(Arrays.toString(arr));
	}
	public static void BubbleSort(int []arr) {
		//外層循環控制輪數
		for(int i=1;i<=arr.length-1;i++) {
			//內層循環控制每輪比較的次數
			for(int j=1;j<=arr.length-i;j++) {
				if(arr[j-1]>arr[j]) {
					//藉助中間變量交換兩個位置上的值
					int temp = arr[j-1];
					arr[j-1]= arr[j];
					arr[j]=temp;
				}
			}
		}	
	}
}

  動態演示:

冒泡排序

 

2. 選擇排序

以升序爲例,在未排序序列中找到最小元素,存放到排序序列的起始位置,然後,再從剩餘未排序元素中繼續尋找最小元素,然後放到已排序序列的末尾。以此類推,直到所有元素均排序完畢。 

代碼:

public class SelectionSort {
	private void mian() {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		SelectionSort(arr);
		 System.out.println(Arrays.toString(arr));
	}

	private void SelectionSort(int[] arr) {
		for(int i =0;i<arr.length-1;i++) {
			int minIndex = i;
			for(int j=i;j<arr.length-1;j++) {
				if(arr[minIndex]>arr[j]) {
					minIndex = j; //記下目前找到的最小值所在的位置
				}
			}
			//在內層循環結束,也就是找到本輪循環的最小的數以後,再進行交換
			if (minIndex != i){
				int temp = arr[i];
				arr[i] = arr[minIndex];
				arr[minIndex] = temp;
			}
		}
	}
}

  

動態演示;

選擇排序

 

 

3. 插入排序

  1. 從第一個元素開始,該元素可以認爲已經被排序;
  2. 取出下一個元素,在已經排序的元素序列中從後向前掃描;
  3. 如果該元素(已排序)大於新元素,將該元素移到下一位置;
  4. 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
  5. 將新元素插入到該位置後;
  6. 重複步驟2~5。

代碼:

public class InsertSort {
	public static void main(String[] args) {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		insertionSort(arr);
		 System.out.println(Arrays.toString(arr));
	}
	private static void insertionSort(int []arr){
	    for(int i=1; i<arr.length; i++){
	        int preIndex = i-1;
	        int current = arr[i];
	        while(preIndex>=0 && arr[preIndex]>current){
	            arr[preIndex+1]=arr[preIndex];
	            preIndex--;
	        }
	        arr[preIndex+1]=current;
	    }
	}
}

  

動態演示:

插入排序

 

4. 快速排序:

 

步驟爲:

  1. 從數列中挑出一個元素,稱爲"基準"(pivot),
  2. 重新排序數列,所有比基準值小的元素擺放在基準前面,所有比基準值大的元素擺在基準後面(相同的數可以到任何一邊)。在這個分區結束之後,該基準就處於數列的中間位置。這個稱爲分區(partition)操作。
  3. 遞歸地(recursively)把小於基準值元素的子數列和大於基準值元素的子數列排序。

遞歸到最底部時,數列的大小是零或一,也就是已經排序好了。這個算法一定會結束,因爲在每次的迭代(iteration)中,它至少會把一個元素擺到它最後的位置去。

代碼:

public class QuickSort {
	public static void main(String[] args) {
		int[] arr = {3,44,38,5,47,15,36,26,27,2,46,4,19,50,48};
		quickSort(arr,0,arr.length-1);
		System.out.println(Arrays.toString(arr));
	}
	private static void quickSort(int[] arr, int low, int high) {

        if (low < high) {
            // 找尋基準數據的正確索引
            int index = getIndex(arr, low, high);

            // 進行迭代對index之前和之後的數組進行相同的操作使整個數組變成有序
            quickSort(arr, 0, index - 1);
            quickSort(arr, index + 1, high);
        }

    }

    private static int getIndex(int[] arr, int low, int high) {
        // 基準數據
        int tmp = arr[low];
        while (low < high) {
            // 當隊尾的元素大於等於基準數據時,向前挪動high指針
            while (low < high && arr[high] >= tmp) {
                high--;
            }
            // 如果隊尾元素小於tmp了,需要將其賦值給low
            arr[low] = arr[high];
            // 當隊首元素小於等於tmp時,向前挪動low指針
            while (low < high && arr[low] <= tmp) {
                low++;
            }
            // 當隊首元素大於tmp時,需要將其賦值給high
            arr[high] = arr[low];

        }
        // 跳出循環時low和high相等,此時的low或high就是tmp的正確索引位置
        // 由原理部分可以很清楚的知道low位置的值並不是tmp,所以需要將tmp賦值給arr[low]
        arr[low] = tmp;
        return low; // 返回tmp的正確位置
    }

}

  

 

動態演示:

快速排序

借用下啊哈算法的圖:

094811yilrz1tkzkvlrriz.png

i和j分別爲左哨兵和右哨兵,這裏樞紐元定爲6,然後分別從左往右(i++)和右往左(j--)開始遍歷

左哨兵查找比6大的元素,右哨兵查找比6小的元素

第一次交換結果

095430axy0qkhxxkktkktk.png

095437kdandfxhbtokk2qh.png

 

第二次交換結果

095448k1kevwlz41373e7k.png

095458ejza15wscjv7iw5c.png

 

095506uz7e1uuukcblhkxv.png

相遇後直接與樞紐元交換

095514cag5fumuqqg5jnsw.png

095530e0jf6p0y6aaaw2ir.png

然後再遞歸排序就行

232129ogop8gk0r8y7l70k.png

232129ogop8gk0r8y7l70k.png

 

 

232129ogop8gk0r8y7l70k.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章