1. 程式人生 > >三種基礎排序演算法(選擇排序、插入排序、氣泡排序)

三種基礎排序演算法(選擇排序、插入排序、氣泡排序)

注:

 圖片轉自點選開啟連結

 以下均使用升序介紹。


選擇排序:

從陣列中找到最小的元素,和第一個位置的元素互換。
 從第二個位置開始,找到最小的元素,和第二個位置的元素互換。
 ........
 直到選出array.length-1個較小元素,剩下的最大的元素自動排在最後一位。

 

 

 

程式碼實現:

    public class Selection {
     
        public static void sort(int[] arr){
            for(int i=0; i<arr.length-1; i++) {
                int minPos = i;
                for (int j = i; j < arr.length; j++) {
                    if (arr[j] < arr[minPos]) {
                        minPos = j;//找出當前最小元素的位置
                    }
                }
                if(arr[minPos]!=arr[i]) {
                    swap(arr,minPos,i);
                }
            }
        }
        public static void swap(int[] arr,int a,int b){
            int temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }

衍生演算法:
雙向選擇排序(每次迴圈,同時選出最大值放在末尾,最小值放在前方)。

程式碼實現:

    public class Selection {
     
        public static void doubleSort(int[] arr){
            for(int i=0; i<arr.length/2-1; i++) {
                int minPos = i,maxPos = arr.length -i -1;
                for (int j = i; j < arr.length -i; j++) {
                    if (arr[j] < arr[minPos]) {
                        minPos = j;
                    }
     
                    if(arr[maxPos] <arr[j]){
                        maxPos = j;
                    }
                }
                if(i!=minPos) {
                    swap(arr,i,minPos);//(1)
                }
                if(maxPos!=arr.length - i - 1) {
                    if (maxPos == i){//若當前最大值在迴圈起始位置,則最大值一定在(1)處被交換到了minPos的位置
                        maxPos = minPos;
                    }
                    swap(arr,maxPos,arr.length -i -1);
                }
            }
        }
        public static void swap(int[] arr,int a,int b){
            int temp = arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }

插入排序:


從第二個元素開始,將當前元素插入到前面對應位置,使當前元素i
和之前元素形成有序陣列。

 

 


比較規則:
 正常:
從第一個元素開始,若當前元素i小於有序陣列中的元素j,則從該元素開始將有序陣列依次後移一位,
並將當前元素i放置到該元素j位置。(插入)

 簡易:
 從有序陣列最後一個元素開始,若當前元素i小於該元素j,則交換當前元素和該元素。

簡易版程式碼實現:

    public class Insertion {
     
        public static void sort(int[] arr){
            int pos,temp;
            for(int i=1;i<arr.length;i++){
                pos = i;
                while(pos!=0&&arr[pos]<arr[pos-1]){
                    temp = arr[pos];
                    arr[pos] = arr[pos-1];
                    arr[pos-1] = temp;
                    pos--;
                }
            }
        }
    }


氣泡排序:


從前往後,依次比較相鄰的兩個數,把較大的數放到後面。一次迴圈,可以在當前最末尾位置得到一個當前最大值。

 

 

 

程式碼實現:

    public class Bubble {
     
     
        public static void sort(int[] arr){
            int temp;
            //依次將最大的數放置到陣列末尾,將第二大的數放到倒數第二位...
            for(int i = 0;i < arr.length-1;i++){
               
                //從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
                for(int j = 0;j < arr.length-1-i;j++){
     
                    if(arr[j]>arr[j+1]) {
                        swap(arr,j,j+1);
                        changed = true;
                    }
                }
            }
        }
     
        public static void swap(int []arr,int a ,int b){
            int temp=arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }

程式碼優化:
在某些時候,迴圈還未終止,整個陣列已經排好序,此時應及時終止迴圈。
(冒泡每次都會比較相鄰兩個數並交換次序不對的組,若一次迴圈後,都沒進行交換,則已經完成排序)

優化程式碼實現:

    public class Bubble {
     
     
        public static void sort(int[] arr){
            int temp;
            boolean changed;
            for(int i = 0;i < arr.length-1;i++){
                changed = false;
                for(int j = 0;j < arr.length-1-i;j++){
     
                    if(arr[j]>arr[j+1]) {
                        swap(arr,j,j+1);
                        changed = true;
                    }
                }
                if(!changed){
                    break;
                }
            }
        }
     
        public static void swap(int []arr,int a ,int b){
            int temp=arr[a];
            arr[a] = arr[b];
            arr[b] = temp;
        }
    }


雞尾酒排序:

 

雞尾酒是氣泡排序的升級版,該排序從左往右找出最大值後,再從右往左
找出最小值,類似雞尾酒攪拌左右迴圈。在某些情況下,優於氣泡排序,
以序列(2,3,4,5,1)為例,雞尾酒排序只需要訪問兩次(升序降序各一次 )
次序列就可以完成排序,但如果使用氣泡排序則需要四次。

 


程式碼實現:

    public class CockTail {
     
        public static void sort(int[] arr){
            //依次將最大的數放置到陣列末尾,將第二大的數放到倒數第二位...
            boolean changed;
            for(int i = 0;i < arr.length/2;i++){
                changed = false;
                //從前往後,比較相鄰兩個數,把大的放在後邊.之前已放置成功的可以不再參與比較
                for(int j = i;j < arr.length-1-i;j++){
     
                    if(arr[j]>arr[j+1]) {
                        swap(arr,j,j+1);
                        changed =true;
                    }
                }
                if(!changed){
                    break;
                }
                for(int j = arr.length-1-i; j > i; j--){
     
                    if(arr[j]<arr[j-1]) {
                        swap(arr,j,j-1);
                        changed = true;
                    }
                }
                if(!changed){
                    break;
                }
            }
        }
     
        public static void swap(int[] arr, int pos1, int pos2){
            int temp = arr[pos1];
            arr[pos1] = arr[pos2];
            arr[pos2] = temp;
        }
    }
---------------------  
作者:seam22  
來源:CSDN  
原文:https://blog.csdn.net/weixin_38830382/article/details/79173384  
版權宣告:本文為博主原創文章,轉載請附上博文連結!