Java基本排序姊妹篇一:選擇排序、冒泡排序、插入排序、計數排序思路講解

一、選擇排序

選擇排序思想:當前元素和之後所有元素進行比較,如果當前元素大於後者,則交換。

示例如圖:

 

代碼展示:

class Test02{
    public static void main(String[] args){
        public static void selectSort(){
        int[] arr={8,5,9,2,7,4,6,1,3};
        for(int i=0;i<arr.length-1;i++){//次數循環,
            for(int j=i+1;j<arr.length;j++){
                if(arr[i]>arr[j]){
                    swap(arr,i,j);//即用-即釋放
                }
            }
        }
        show(arr);
    }
        public static void show(int[] arr){
                //打印結果示例:[1,2,3,4,5,6,7,8,9]
                String s="[";
                for(int i=0;i<arr.length;i++){
                    if(i==arr.length-1){
                        s+=arr[i]+"]";
                    }else{
                        s+=arr[i]+",";
                    }
                }
                System.out.println(s);
            }
        public static void swap(int[] arr,int i,int j){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
}

代碼解釋:

循環次數規律相當於數字倒三角的行數規律:for(int i=0;i<arr.length-1;i++),i<arr.length-1,-1是因爲我們發現每排一次就排好一個相對最小數字,一共9個數字,排八次,第8次比較的就是最後兩個數字,比完就排好了。數組長度爲9 ,9 - 1 = 8 ,i 是從0 開始定義的,[ 0 ,8 )一共8個數字,循環8次即可。

比較次數規律相當於數字倒三角的數字規律:for(int j=i+1;j<arr.length;j++),依圖可得,數組下標與比較次數之間差1,即  j=i+1 ,第一次比較爲比較次數最多的一次爲8次,所以j<arr.length。

 

二、冒泡排序

冒泡排序思想:從左到右兩者之間依次比較

示例如圖

 

class Test02{
    public static void main(String[] args){
       public static void bubbleSort(){
        int[] arr={9,1,5,2,7,4,6,1,3};
        for(int i=0;i<arr.length-1;i++){//-1是少一輪比較
            for(int j=0;j<arr.length-1-i;j++){//-1避免重複比較和角標越界
                if(arr[j]>arr[j+1]){
                    swap(arr,j,j+1);
                }
            }
        }
        show(arr);
    }
        public static void show(int[] arr){
                String s="[";
                for(int i=0;i<arr.length;i++){
                    if(i==arr.length-1){
                        s+=arr[i]+"]";
                    }else{
                        s+=arr[i]+",";
                    }
                }
                System.out.println(s);
            }
        public static void swap(int[] arr,int i,int j){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
}

 

代碼解釋:

for(int i=0;i<arr.length-1;i++),解釋同上

for(int j=0;j<arr.length-1-i;j++),j<arr.length-1-i:比較次數最多的是第一輪比較8 次 ,數組長度 9 ,9 - 1 = 8 ,所以 - 1 ;- i 是因爲 每循環一輪比較次數減少 1 次 ,建立它與循環次數之間的關係即爲 arr.length - i 。

 

三、插入排序

插入排序思想:如果當前數字左邊有數字,且左邊數字大於當前數字時,交換。

代碼展示:

class Test02{
    public static void main(String[] args){
       public static void insertSort(){
        int[] arr={8,5,9,2,7,4,6,1,3};
        for(int i=1;i<arr.length;i++){
            for(int j=i;j>0&&arr[j-1]>arr[j];j--){//插入排序思路體現
                swap(arr,j,j-1);
            }
        }
        show(arr);
    }
        public static void show(int[] arr){
                String s="[";
                for(int i=0;i<arr.length;i++){
                    if(i==arr.length-1){
                        s+=arr[i]+"]";
                    }else{
                        s+=arr[i]+",";
                    }
                }
                System.out.println(s);
            }
        public static void swap(int[] arr,int i,int j){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
}

 

此段代碼需要優化,下篇文章講解。

 

四、計數排序

計數排序思想:將數字與角標進行規整

示例如圖:

代碼展示:

class Test02{
    public static void main(String[] args){
      public static void countSort(){
        int[] arr={8,5,9,2,7,4,6,1,3,10,-3,-2,-10};
        int min=arr[0];
        int max=arr[0];
        for(int i=0;i<arr.length;i++){
            if(arr[i]>max){
                max=arr[i];
            }
            if(arr[i]<min){
                min=arr[i];
            }
        }
        int[] nums=new int[max-min+1];//計算數組長度
        int offset=min;
        for(int i=0;i<arr.length;i++){
            nums[arr[i]-offset]++;//表示 arr[i]這個數字出現一次並累加
        }
        int index=0;
        for(int i=0;i<nums.length;i++){
            if(nums[i]!=0){ //num[i]表示 i + offset 這個數據出現的次數
                for(int j=0;j<nums[i];j++){
                    arr[index++]=i+offset;
                }
            }
        }
        show(arr);
    }
        public static void show(int[] arr){
                String s="[";
                for(int i=0;i<arr.length;i++){
                    if(i==arr.length-1){
                        s+=arr[i]+"]";
                    }else{
                        s+=arr[i]+",";
                    }
                }
                System.out.println(s);
            }
        public static void swap(int[] arr,int i,int j){
                int temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
}

思路展示:

這道題的關鍵是 需要排列的數據中有負數,那麼要如何存儲這些負數呢?我們知道計數排序的思想是將數字與角標進行規整,即需要建立起數組下標與數據之間的關係,所以引入了變量 offset ,這樣就有合適的位置存儲這些負數了。

  1. 先獲取最大值和最小值 min = - 10  max = 10
  2. 根據最大值最小值 計算 存儲數據的數組長度  max - min + 1
  3. 計算偏移量 offset   數組角標 = 數據 - offset     計算得出offset =  - 10

 

下篇文章有對冒泡排序和插入排序代碼的優化講解,有需要的主頁找哇~同時對for循環不清楚的我主頁也有講解,希望對大家有幫助~

 

 

 

 

 

 

 

 

發佈了16 篇原創文章 · 獲贊 25 · 訪問量 3146
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章