Java淺談兩種常用的排序

常用的排序方法有多種,這裏只說說個人對選擇排序和冒泡排序這兩個最常用的排序方法的一些看法。

   首先,這裏是按排序規則是按從小到大的順序排序。然後,排序方法中接收的只有一個參數,即一個數組名。

最後,排序後並未將排序後的數組元素依次輸出,故而返回值是void,至於輸出操作,可另外自行定義。

   下面是具體的介紹。

   1.選擇排序

       代碼示例:

    for(inti=0;i<arr.length-1;i++){

       for(intj=i+1;j<arr.length;j++){

         if(arr[i]>arr[j]){

            swap(arr,i,j);

         }

       }

    }

        選擇排序的思想是依次找到數組中的相對最小元素,並依次將其放於相應位置上。具體說來就是先找到最小元素,將其放於數組中第一個元素的位置,然後找到第二小元素,將其放於數組中第二個元素的位置。具體做法是讓數組中第一個元素與後面所有元素進行比較,如果後面的元素比第一個元素小,則將它們位置互換,然後讓當前第一個元素繼續與後面的元素比較,也就是說,確保在已比較的元素中,當前第一個元素是最小的。

      這樣的比較思想需要通過雙層for循環才能完成。具體如下:

        外層循環:for(inti=0;i<arr.length-1;i++)

 外層循環控制比較元素的起始位置,即當起始位置爲0時,要比較的是角標爲0的元素和其後面的元素,依次類推。循環中之所以控制條件是i<arr.length-1而不是i<arr.length,是因爲角標爲arr.length-2的元素是數組中的倒數第二頁元素,而與它進行比較的是角標爲arr.length-1的元素,即最後一個元素。也就是說,此次比較是排序中的最後一次元素比較。另外,如果循環控制條件改爲i<arr.length,由於內循環中有j=i+1語句,那麼將此時j爲arr.length,造成角標越界,產生錯誤。綜上兩種情況,循環控制條件爲i<arr.length-1是最佳也是最合理的選擇。

        內層循環: for(intj=i+1;j<arr.length;j++){

         if(arr[i]>arr[j]){

            swap(arr,i,j);

         }

       }
內存循環主要負責元素大小比較的具體操作,j=i+1語句決定了此層循環中與指定比較位置元素比較的元素開始位置,即此層循環中i的值不變。另外,互換位置操作是調用了一個函數swap進行實現的,這裏不對swap進行另述,它的功能就是將指定數組中的指定位置的兩個元素互換位置,而接收的參數中有數組名,這是必須的,因爲它代表着引用地址,通過它操作對應的實際數組。
 

   2.冒泡排序

代碼示例:

for(inti=0;i<arr.length-1;i++){

       for(intj=0;j<arr.length-i-1;j++){

         if(arr[j]>arr[j+1]){

            swap(arr,i,j);

         }

       }

  }

       冒泡排序的思想是將數組中的前一個元素a與後一個元素b進行比較,如果a>b,則將二者位置互換。否則不進行任何操作。

       具體是:第一個元素與第二元素比較,並進行相應操作。之後,第二個元素與第三個元素進行比較,並完成相應操作。。。依此方式完成所有元素的比較。要想在這種思想下把數組中所有元素比較完,需要雙層for循環才能完成。

       外層循環:for(inti=0;i<arr.length-1;i++)

外層循環並沒有什麼特別的地方,可以看出,它是最常見的for循環形式。它控制着內層循環元素比較的輪數,其中循環控制條件是i<arr.length-1,也就是說外層循環的次數是數組元素個數減1,這是必然的,因爲如果數組中只有兩個元素,那麼只需要一輪比較即可。

  內層循環:for(intj=0;j<arr.length-i-1;j++){

         if(arr[j]>arr[j+1]){

            swap(arr,i,j);

         }

       }

內層循環控制着要進行比較的元素的角標範圍,而且要進行判斷並作出相應操作。

冒泡排序的思想決定了排序過程結果是最大的先排到數組最末位置,然後次大的依次排其左邊,這是針對內層循環每輪的操作結果而言的(這裏要注意,在選擇排序中,其排序思想決定了先排的是最小元素,且放到了數組首位置,這點正好與冒泡排序相反)。

內層循環的控制條件是i<arr.length-i-1,它控制着要比較的元素的角標值範圍。這裏要注意,j的初值不變,是0,範圍是通過arr.length-i-1來確定,arr.length-i是隨着外循環的i的值來改變要比較元素的範圍,但是又減1,即arr.length-i-1是因爲,每次比較,都是小角標元素與其右邊相鄰的大角標元素比較。外循環的第一輪循環時,所有元素進行比較,最後的一次比較是數組中倒數第二個元素與其右邊元素,即倒數第一個元素比較。此時倒數第二個元素的角標是j=arr.length-i-2,而判斷條件中的arr[j+1]正是倒數第一個元素。也就是說,如果j=arr.length-i-1時,將出現角標越界情況,導致出現錯誤,所以,控制條件設爲j<arr.length-i-1,即j的最大值只能是j=arr.length-i-2。其實,j=arr.length-i-1時,它的右邊已沒有元素了,也不必進行比較了。綜上兩方面來看,將控制條件設爲j<arr.length-i-1是最佳且是最合理的,這個原因跟選擇排序中內循環控制條件的設置原因類似。

swap(arr,i,j)是調用的交換數組兩元素位置的一個函數,這與上面選擇排序中的用法一樣,因爲這裏只是討論排序,所以對swap函數不做過多論述。

選擇排序和冒泡排序有着不同甚至某些地方相反的思想,但其中的循環控制條件的設定又有着相似的原理。其實,只要理解了其中一種排序方法,就不難理解另外一種了。

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