java 8 新特性(二) stream API
氣泡排序
想必只要是接觸過演算法的同學,都必聽過氣泡排序這四個大字,哈哈。可以說是排序演算法中最簡單,最基礎的一種。其名字的由來正是因為元素在整個排序過程就像碳酸飲料中的氣泡一點一點浮上水面,所以稱之為氣泡排序(Bubble Sort)。
過程
氣泡排序的整個過程用一句話就可以總結(我們這裡假設排好序的序列是從小到打的順序):
遍歷序列N次,每次遍歷的過程中,如果左邊的元素大於右邊的元素,那麼就將他們交換。
接下來我們舉一個具體例子說明:
現在有上述一個無序序列,我們通過氣泡排序將其排列成從左向右從小到大的有序序列。第一次遍歷,用來確定整個序列中最大的元素的位置。
拿9,8兩個元素進行比較,由於9 > 8 所以他們進行交換後再進行指標後移:
然後繼續將指標指向的位置上的元素和其後面相鄰元素相比較,此時9 > 7,所以我們將其互換位置後再進行指標後移:
在這裡插入圖片描述
此時依舊拿當前指標指向的元素和其後面相鄰元素相比較,此時9 > 6 ,所以我們將 9,6交換位置後再進行指標後移:
在這裡插入圖片描述
接下來依舊是重複之前的動作,即拿當前指標指向的元素和其後面相鄰的元素相比較,此時9 > 5 ,所以我們將9,5交換位置後再進行指標後移:
在這裡插入圖片描述
此時已經到達了序列的最尾端,所以第一次遍歷結束,而在遍歷結束後,確定了9這一元素的位置。
總結一下上面遍歷過程:如果arr[i] > arr[i + 1]則將兩個元素交換然後指標後移,反之則只將指標後移後繼續判斷。
上面是一個遍歷過程,確定了序列中最大值的最終位置,我們可以將剩下的問題看成一個子問題,將下圖的序列排序成一個從小到大的有序序列,那麼我們依舊可以按照上面提到的遍歷方式去確定這個序列中的最大值的位置。
在這裡插入圖片描述
對上圖的無序序列執行一遍遍歷過程之後,得到的序列如下:
在這裡插入圖片描述
此時我們再將問題分解成一個子問題,即對序列7,6,5進行排序。這樣一直分解下去最終問題縮小到最小就是:只剩下一個元素5,對其進行排序,那麼這個時候也就確定了起初整個序列中所有元素的位置,也就得到了一個有序序列:5,6,7,8,9。
程式碼實現
我們現在對以上思路使用程式碼去落地實現:
1.遍歷陣列N次去確定N個元素的位置,可以使用for迴圈;
2.在每次遍歷中,要從前向後比較每個位置的元素,所以還需要一個for迴圈,所以為雙重迴圈;
3.指標則使用for迴圈中的遍歷變數作為指標。
Java語言實現
public void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2)
return;
//外層for控制每次遍歷的終止點 即內層迴圈最終確定的元素的位置
for (int end = arr.length - 1; end > 0; end--) {
//內層for用於比較和交換
for (int i = 0; i < end; i++) {
if (arr[i] > arr[i + 1])
swap(arr, i, i + 1);
}
}
}
其中swap()函式是為了程式碼看上去簡潔而封裝的一個交換陣列內兩個位置上的元素的函式,具體程式碼如下:
public void swap(int[] arr, int p1,int p2){
int temp = arr[p1];
arr[p1] = arr[p2];
arr[p2] = temp;
}
Golang語言實現
func BubbleSort(arr []int) {
if len(arr) == 0 {
return
}
for end := len(arr) - 1; end > 0; end-- {
for i := 0; i < end; i++ {
if arr[i] > arr[i+1] {
swap(arr,i,i + 1)
}
}
}
}
swap()函式程式碼如下:
func Swap(arr []int,i, j int) {
temp := arr[i]
arr[i] = arr[j]
arr[j] = temp
}