1. 程式人生 > 其它 >Java整數陣列排序

Java整數陣列排序

整數陣列中的元素包含: 負數 0 正數 可能會有重複 隨機數範圍為-49到+49 共100個

排序演算法: 選擇 冒泡 插入 快速 希爾 歸併 桶

程式碼均為升序 倒序的部分在具體的位置會有標記

package a2_sort;

import java.util.Random;

public class a01_selection {

    // 選擇排序核心思想  不斷的選擇出最小值  換位到序列最左側
    public static int[] selectionSort(int[] arr) {

        for (int i = 0; i < arr.length; i++) {
            
int min = arr[i]; int index = i; for (int j = i+1; j < arr.length; j++) { // 換成< 就是降序 if (min > arr[j]){ min = arr[j]; index = j; } } int temp = arr[i]; arr[i]
= min; arr[index] = temp; } return arr; } public static void main(String[] args) { int[] arr = hundred(); int[] res = selectionSort(arr); for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); } }
public static int[] hundred(){ int[] arr = new int[100]; int res = 0; for (int i = 0; i < arr.length; i++) { res = new Random().nextInt(50); if (i>50) {res = res*(-1);} arr[i] = res; } return arr; } }
1 selectSort
package a2_sort;

import java.util.Random;

public class a02_bubble {

    // 氣泡排序核心思想  像冒泡一樣  不斷的選擇出最大值  換位序列最右側
    public static int[] bubbleSort(int[] arr) {

        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]){
                    int temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        return arr;
    }

    public static void main(String[] args) {
        int[] arr = hundred();
        int[] res = bubbleSort(arr);
        for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
2 bubbleSort
package a2_sort;

import java.util.Random;

public class a03_insert {

    // 插入排序核心思想:  不斷和左側元素比較  將較小的元素  插入到左側
    public static int[] insertionSort(int[] arr) {

        for (int i = 1; i < arr.length; i++) {
            for (int j = i; j > 0 ; j--) {
                // 換成>  就是降序  和選擇排序氣泡排序不同  正好相反
                if (arr[j]<arr[j-1]){
                    int temp = arr[j-1];
                    arr[j-1] = arr[j];
                    arr[j] = temp;
                }

            }
        }
        return arr;
    }
    
    public static void main(String[] args) {
        int[] arr = hundred();
        int[] res = insertionSort(arr);
        for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
3 insertionSort
package a2_sort;

import java.util.Random;

public class a04_quick {

    // 快速排序核心思想: 2個哨兵對向出發  將相遇的位置歸位  分成左右兩序列後  類推
    public static void quickSort(int[] arr, int left, int right) {
        if (left>right)return;

        int i,j,temp,t;
        i=left;
        j=right;
        temp=arr[left];

        while (i!=j){
            // 分別換成<=和>=  就是降序  哨兵j讓小於基準的值 存放在右側
            while (arr[j]>=temp && i<j)
                j--;
            while (arr[i]<=temp && i<j)
                i++;

            if (i<j){
                t=arr[i];
                arr[i]=arr[j];
                arr[j]=t;
            }
        }

        arr[left] = arr[i];
        arr[i] = temp;

        quickSort(arr, left, i-1);
        quickSort(arr, i+1, right);
    }

    public static void main(String[] args) {
        int[] arr = hundred();
        quickSort(arr,0,arr.length-1);
        for (int temp: arr) { if(temp != arr[arr.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
4 quickSort
package a2_sort;

import java.util.Random;

public class a05_shell {
    public static int[] shellSort(int[] arr){

        // 希爾排序核心思想: 將步長減半  然後進行插入排序
        for (int i = arr.length/2; i > 0 ; i/=2) {

            for (int j = i; j < arr.length ; j++) {
                for (int k = j; k > 0 && k+1 > 0 ; k--) {
                    // 換成>  就是降序
                    if (arr[k]<arr[k-1]){
                        int temp = arr[k-1];
                        arr[k-1] = arr[k];
                        arr[k] = temp;
                    }
                }
            }

        }
        return arr;
    }

    public static void main(String[] args) {
        int[] arr = hundred();
        int[] res = shellSort(arr);
        for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ",");else System.out.println(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
5 shellSort
package a2_sort;

import java.util.Random;

public class a06_merge {

    // 歸併排序核心思想:  將陣列不斷分割  最終進行比較 排序  然後歸併成一個有序陣列
    public static void mergeArr(int[] arr, int left, int mid, int right){
        int[] b = new int[arr.length];
        int p1=left, p2=mid+1, k=left;

        while (p1<=mid && p2<=right) {
            // 換成>=  就是降序
            if(arr[p1]<=arr[p2])
                b[k++] = arr[p1++];
            else
                b[k++] = arr[p2++];
        }

        while (p1<=mid) b[k++] = arr[p1++];
        while (p2<=right) b[k++] = arr[p2++];

        for (int i = left; i <= right; i++)
            arr[i] = b[i];
    }

    public static void mergeSort(int[] arr, int left, int right){
        if (left>=right)return;
        int mid=(left+right)/2;
        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        mergeArr(arr, left, mid, right);
    }

    public static void main(String[] args) {
        int[] arr = hundred();
        mergeSort(arr, 0, arr.length-1);
        for (int temp: arr) { if(temp != arr[arr.length-1]) System.out.print(temp + ","); else  System.out.println(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
6 mergeSort
package a2_sort;

import java.util.Random;

public class a07_bucket {

    // 桶排序核心思想: 陣列的索引值是有序的  利用這個特點  在新陣列中進行統計個數
    public static int[] bucketSort(int[] arr){

        int max = Integer.MIN_VALUE;
        for (int i = 0; i < arr.length; i++) {
            max = Math.max(max, arr[i]);
        }

        int[] bucket = new int[max+1];
        for (int i = 0; i < arr.length; i++) {
            bucket[arr[i]]++;
        }

        int res = 0;
        // 降序為  int j = arr.length-1; j > 0; j--
        for (int j = 0; j < bucket.length; j++) {
            while (bucket[j]-- > 0)
                arr[res++] = j;
        }

        return arr;
    }

    public static void main(String[] args) {
        int[] arr = {1,3,2,5,4,9,6,7,8,0};
        int[] res = bucketSort(arr);
        for (int temp: res) { if(temp != res[res.length-1]) System.out.print(temp + ","); else System.out.print(temp); }
    }

    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
7 bucketSort
package a2_sort;

import java.util.Arrays;
import java.util.Random;

// 解決一個問題  桶排序無法對負數進行排序
public class a08_bucket {
    public static void main(String[] args) {
        int[] arr = hundred();

        int[] f = getArr1(arr);     // 取出負數
        f = bucket1(f);             // 負數轉正  升序
        f = reverseArr(f);          // 反轉成倒序
        f = recover(f);             // 正數恢復成負數

        int[] n = getArr2(arr);     // 取出正數
        n = bucket2(n);             // 普通桶排序 將陣列排序

        int[] m = mergeArray(f,n);  // 負數的陣列 和 正數的陣列 合併

        printArr(m);

        // 陣列中的元素有100個  目測排序的準確性,數量  較耗時
        // 所以使用陣列的工具來驗證  比較隨機生成的陣列 和 自己手寫的方法產生的陣列 應該一致
        Arrays.sort(arr);
        int[] arrSort = arr;
        System.out.println("兩個陣列是否相同: : " + Arrays.equals(arr, m));
        // equalsArr(arr,m);
    }

    // 遍歷陣列m  要像Arrays.toString一樣  兩端有[]  元素之間有逗號和1個空格  最後沒有
    public static void printArr(int[] m){
        String res = "[";
        int len = m.length-1;

        for (int i = 0; i < len; i++) {
            res += m[i] + ", ";
        }

        res += m[len] + "]";

        System.out.println(res);
        System.out.println(Arrays.toString(m));

        //  採用str拼接的方式
        /*String res1 = "[";
        String res2 = "";

        for (int i = 0; i < m.length-1; i++) {
            res2 +=m[i];
            res2 +=", ";
        }

        String res3 = "" + m[m.length-1];
        String res4 = "]";
        System.out.println(res1+res2+res3+res4);*/
    }

    // 比較arr和m這兩個陣列有什麼區別
    public static void equalsArr(int[] arr, int[] m){
        System.out.print("陣列arr的長度: " + arr.length + "m的長度: " + m.length);
        System.out.println(arr.length==m.length);

        System.out.print("比較2個數組中的元素是否相同: ");
        int p1=0, p2=0;
        boolean flag ;

        for (int i = 0; i < arr.length; i++) {
                if (arr[i]==m[i]) {
                    m[i] = -1;
                } else if(i==m.length) {
                    System.out.println("2個數組不相同");
                    flag = false;
                    return;
                }
        }
    }

    // 合併 負數的陣列 和 正數的陣列
    public static int[] mergeArray(int[] f, int[] n){
        int p1=f.length, p2=n.length;
        int[] res = new int[p1+p2];

        // 先將f這個負數陣列填充到res中  然後在剩餘位置將n這個正數陣列填充  總長100
        for (int i = 0; i < p1; i++)
            res[i] = f[i];

        int idx = p1;
        for (int j = 0; j < p2; j++)
            res[idx++] = n[j];

        return res;
    }

    // 讓負數陣列 變成 正數陣列  方便後續的桶排序
    public static int[] recover(int[] f){
        for (int i = 0; i < f.length; i++)
            f[i] = f[i] * (-1);
        return f;
    }

    // 將升序的陣列  變成  倒序  因為最終的效果為-49到+49  負數的部分就應該是倒序
    public static int[] reverseArr(int[] f){
        int temp = 0;
        for (int i = 0; i < f.length/2; i++) {
            temp = f[i];
            f[i] = f[f.length-1-i];
            f[f.length-1-i] = temp;
        }
        return f;
    }

    // 將正數的陣列進行排序  必須使用桶排序
    public static int[] bucket2(int[] n){
        int max = Integer.MIN_VALUE;
        for (int i = 0; i < n.length; i++)
            max = Math.max(max, n[i]);

        int[] b = new int[max+1];
        for (int i = 0; i < n.length; i++)
            b[n[i]]++;

        int idx = 0;
        for (int j = 0; j < b.length; j++) {
            while (b[j]-- >0)
                n[idx++] = j;
        }
        return n;
    }

    // 將負數陣列升序  因為必須使用桶排序  涉及到的索引都要是正數  所以負數要暫時轉換成正數
    public static int[] bucket1(int[] f){
        for (int i = 0; i < f.length ; i++)
            f[i] = f[i] * (-1);

        int max = Integer.MIN_VALUE;
        for (int i = 0; i < f.length; i++)
            max = Math.max(max, f[i]);

        int[] b = new int[max+1];
        for (int i = 0; i < f.length; i++)    b[f[i]]++;

        int fIdx = 0;
        for (int j = 0; j < b.length; j++) {
            while (b[j]-- > 0)
                f[fIdx++] = j;
        }

        return f;
    }

    // 取出陣列arr中存放的正數 和 0  特意將0放在這裡存放屬於正數的陣列
    public static int[] getArr2(int[] arr){
        int ne = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]>=0) ne++;
        }

        int nIdx = 0;
        int[] n = new int[ne];

        for (int i = 0; i < arr.length; i++) {
            if (arr[i]>=0)
                n[nIdx++] = arr[i];

        }
        return n;
    }

    // 取出陣列arr中的負數  形成一個新的陣列  命名為: 負數的陣列
    public static int[] getArr1(int[] arr){

        int positiveNumber = 0;
        for (int i = 0; i < arr.length; i++) {
            if (arr[i]<0) positiveNumber++;
        }

        int fIdx = 0;
        int[] f = new int[positiveNumber];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]<0){
                f[fIdx++]=arr[i];
            }
        }
        return f;
    }

    // 隨機生成100個整數  含負數 0 正數 有重複  範圍-49到49
    public static int[] hundred(){
        int[] arr = new int[100];
        int res = 0;
        for (int i = 0; i < arr.length; i++) {
            res = new Random().nextInt(50);
            if (i>50) {res = res*(-1);}
            arr[i] = res;
        }
        return arr;
    }
}
8 讓桶排序可以排序負數