java實現12種排序算法


Java實現的12種排序

2019-01-05

 

 

 

一.冒泡排序及其實現

二.希爾排序及其實現

三.插入排序及其實現

四.插入排序及其實現

五.快速排序及其實現

六.合並排序及其實現

七.計數排序及其實現

八.基數排序及其實現

九.   桶排序及其實現

 十.    堆排序及其實現

   十一.二叉樹排序及有序集合

         十二.利用集合的4種排序排序方式

 

 


一.冒泡排序及其實現

一.home→包

BubbleSort→類

           main→主函數

                      bubbleSort1()→冒泡排序1

                      bubbleSort2()→冒泡排序優化1

                      bubbleSort3()→冒泡排序優化2

 1 package home;
 2 import java.util.Arrays;
 3 
 4 /**
 5  * 冒泡排序的三種寫法
 6  * @author Stringer123
 7  * @version 1.0
 8  * 
 9  */
10 public class BubbleSort {
11     
12     public static void main(String[] args) {
13         // TODO Auto-generated method stub
14         int[] arr = { 1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22 };
15         // int[] b1 = bubbleSort1(arr);
16         // int[] b1 = bubbleSort2(arr);
17         int[] b1 = bubbleSort3(arr);
18 
19         // 遍歷方式1:java 8新特性(利用Lambda表達式)→通過轉成流輸出數組
20         Arrays.stream(b1).forEach(item -> {
21             System.out.print(item + " ");
22         });
23         System.out.println();
24 
25         // 遍歷方式2:通過傳統for循環遍歷
26         for (int i = 0; i < b1.length; i++) {
27             System.out.print(b1[i] + " ");
28         }
29         System.out.println();
30 
31         // 遍歷方式3:通過增強for循環遍歷(也成for-each循環)
32         for (int i : b1) {
33             System.out.print(i + " ");
34         }
35         System.out.println();
36 }

(1) 冒泡排序的第一種實現,沒有任何優化

private static int[] bubbleSort1(int[] a) {
        System.out.println("bubbleSort1的排序結果:");
        int i, j;
        int n = a.length;
        for (i = 0; i < n; i++) {
            for (j = 1; j < n - i; j++) { // 前面的數字大於后面的數字就交換
                if (a[j - 1] > a[j]) { // 交換a[j-1]和a[j]
                    int temp;
                    temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;
                }
            }
        }
        return a;
    }

(2) 冒泡排序的第一種優化實現

下面開始考慮優化,如果對於一個本身有序的序列,或則序列后面一大部分都是有序的序列,上面的算法就會浪費很多的時間開銷,這里設置一個標志flag,如果這一趟發生了交換,則為true,否則為false。明顯如果有一趟沒有發生交換,說明排序已經完成。

/**
     * 設置一個標志,如果這一趟發生了交換,則為true,否則為false。明顯如果有一趟沒有發生交換,說明排序已經完成。
     * 
     * @param a
     * @return
     */
    private static int[] bubbleSort2(int[] a) {
        System.out.println("bubbleSort2的排序結果:");
        int j;
        int n = a.length;
        boolean flag = true;// 發生了交換就為true, 沒發生就為false,第一次判斷時必須標志位true。
        while (flag) {
            flag = false;// 每次開始排序前,都設置flag為未排序過
            for (j = 1; j < n; j++) {
                if (a[j - 1] > a[j]) {// 前面的數字大於后面的數字就交換
                    // 交換a[j-1]和a[j]
                    int temp;
                    temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;

                    // 表示交換過數據;
                    flag = true;
                }
            }
            n--;// 減小一次排序的尾邊界
        } // end while
        return a;
    }

(3) 冒泡排序的第一種優化實現

再進一步做優化。比如,現在有一個包含1000個數的數組,僅前面100個無序,后面900個都已排好序且都大於前面100個數字,那么在第一趟遍歷后,最后發生交換的位置必定小於100,且這個位置之后的數據必定已經有序了,也就是這個位置以后的數據不需要再排序了,於是記錄下這位置,第二次只要從數組頭部遍歷到這個位置就可以了。如果是對於上面的冒泡排序算法2來說,雖然也只排序100次,但是前面的100次排序每次都要對后面的900個數據進行比較,而對於現在的排序算法3,只需要有一次比較后面的900個數據,之后就會設置尾邊界,保證后面的900個數據不再被排序。

/**
     * 設置一個標志,如果這一趟發生了交換,則為true,否則為false。明顯如果有一趟沒有發生交換,說明排序已經完成。
     * 
     * @param a
     * @return
     *
     */
    public static int[] bubbleSort3(int[] a) {
        System.out.println("bubbleSort3的排序結果:");
        int j;
        int n = a.length;
        boolean flag = true;// 發生了交換就為true, 沒發生就為false,第一次判斷時必須標志位true。
        while (flag) {
            flag = false;// 每次開始排序前,都設置flag為未排序過
            for (j = 1; j < n; j++) {
                if (a[j - 1] > a[j]) {// 前面的數字大於后面的數字就交換
                    // 交換a[j-1]和a[j]
                    int temp;
                    temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;

                    // 表示交換過數據;
                    flag = true;
                }
            }
            n--;// 減小一次排序的尾邊界
        } // end while
        return a;
    }// end
}

(4) 三種方法console輸出顯示:

 

二.希爾排序及其實現

1)基本思想

先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,列中的記錄“基本有序”時,再對全體記錄進行依次直接插入排序。

2)操作方法

1. 選擇一個增量序列t1,t2,…,tk,其中ti>tj,tk=1;

2. 按增量序列個數k,對序列進行k 趟排序;

3. 每趟排序,根據對應的增量ti,將待排序列分割成若干長度為m 的子序列,分別對各子表進行直接插入排序。僅增量因子為1 時,整個序列作為一個表來處理,表長度即為整個序列的長度。

3)希爾排序示例

4)希爾排序代碼實現

package home;
import java.util.Arrays;

public class ShellSort {
    /**希爾排序的原理:根據需求,如果你想要結果從大到小排列,它會首先將數組進行分組,然后將較大值移到前面,較小值
     * 移到后面,最后將整個數組進行插入排序,這樣比起一開始就用插入排序減少了數據交換和移動的次數,可以說希爾排序是加強
     * 版的插入排序
     * 拿數組5, 2, 8, 9, 1, 3,4來說,數組長度為7,當increment為3時,數組分為兩個序列
     * 5,2,8和9,1,3,4,第一次排序,9和5比較,1和2比較,3和8比較,4和比其下標值小increment的數組值相比較
     * 此例子是按照從大到小排列,所以大的會排在前面,第一次排序后數組為9, 2, 8, 5, 1, 3,4
     * 第一次后increment的值變為3/2=1,此時對數組進行插入排序,
     *實現數組從大到小排
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] arr = { 5, 2, 8, 9, 1, 3,4 };
        int[] b1 = shellSort(arr);

        System.out.println("shellSort排序結果:");

        Arrays.stream(b1).forEach(item -> {
            System.out.print(item + " ");
        });

    }

    private static int[] shellSort(int[] a) {
        // TODO Auto-generated method stub
        int j = 0;
        int temp = 0;
        // 每次將步長縮短為原來的一半,increment為步長
        for (int increment = a.length / 2; increment > 0; increment /= 2) {
            for (int i = increment; i < a.length; i++) {
                temp = a[i];
                for (j = i; j >= increment; j -= increment) {
                    if (temp > a[j - increment])// 如想從小到大排只需修改這里
                    {
                        a[j] = a[j - increment];
                    } else {
                        break;
                    }

                }
                a[j] = temp;
            }

        }
        return a;
    }

}

5)控制台輸出結果:

三.插入排序及其實現

1)插入排序代碼實現:

package home;

import java.util.Arrays;

public class InsertSort {

    /**
     * 插入排序
     * 
     * 從第一個元素開始,該元素可以認為已經被排序 取出下一個元素,在已經排序的元素序列中從后向前掃描
     * 如果該元素(已排序)大於新元素,將該元素移到下一位置 重復步驟3,直到找到已排序的元素小於或者等於新元素的位置 將新元素插入到該位置中 重復步驟2
     * 
     * @param numbers
     *            待排序數組
     */

    public static void main(String[] args) {
        int[] arr = { 1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22 };
        int[] b1 = insertSort(arr);
        
        System.out.println("insertSort排序結果:");
        Arrays.stream(b1).forEach(item -> {System.out.print(item + " ");});
    }

    private static int[] insertSort(int[] a) {
        int n = a.length;
        int temp = 0;
        int j = 0;

        for (int i = 0; i < n; i++) {
            temp = a[i];
            // 假如temp比前面的值小,則將前面的值后移
            for (j = i; j > 0 && temp < a[j - 1]; j--) {
                a[j] = a[j - 1];
            }
            a[j] = temp;
        }
        return a;
    }
}

2)控制台輸出結果:

四.插入排序及其實現

 

1)選擇排序代碼實現

package home;

public class ChooseSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 1, 3, 2, 45, 65, 33, 12 };
        int n = arr.length;
        // 選擇排序的優化
        for (int i = 0; i < n - 1; i++) {// 做第i趟排序
            int k = i;
            for (int j = k + 1; j < n; j++) {// 選最小的記錄
                if (arr[j] < arr[k]) {
                    k = j; // 記下目前找到的最小值所在的位置
                }
            }
            // 在內層循環結束,也就是找到本輪循環的最小的數以后,再進行交換
            if (i != k) { // 交換a[i]和a[k]
                int temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }
        }
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

2)控制台輸出結果:

五.快速排序及其實現

 

一.快速排序1//固定的切分方式

package home;

public class ChooseSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("chooseSort排序結果:");
        int[] arr = { 1, 3, 2, 45, 65, 33, 12 };
        int n = arr.length;
        // 選擇排序的優化
        for (int i = 0; i < n - 1; i++) {// 做第i趟排序
            int k = i;
            for (int j = k + 1; j < n; j++) {// 選最小的記錄
                if (arr[j] < arr[k]) {
                    k = j; // 記下目前找到的最小值所在的位置
                }
            }
            // 在內層循環結束,也就是找到本輪循環的最小的數以后,再進行交換
            if (i != k) { // 交換a[i]和a[k]
                int temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }
        }
        for (int num : arr) {
            System.out.print(num + " ");
        }
    }
}

輸出結果:

二.快速排序的優化

package home;

//對於基准位置的選取:隨機切分和三取樣切分。固定切分的效率並不是太好,隨即切分是常用的一種切分,效率比較高,最壞情況下復雜度有可能為O(N^2),對於三數取中選擇基准點是最理想的一種.

public class QuickSort1 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("快速排序優化算法:");
        int[] a = {12,20,5,16,15,1,30,45,23,9};
        int start = 0;
        int end = a.length-1;
        sort(a,start,end);
        for(int i = 0; i<a.length; i++){
             System.out.print(a[i]+" ");
         }
    }
    public static int partition(int []array,int lo,int hi){
        //三數取中
        int mid=lo+(hi-lo)/2;
        if(array[mid]>array[hi]){
            swap(array[mid],array[hi]);
        }
        if(array[lo]>array[hi]){
            swap(array[lo],array[hi]);
        }
        if(array[mid]>array[lo]){
            swap(array[mid],array[lo]);
        }
        int key=array[lo];
        
        while(lo<hi){
            while(array[hi]>=key&&hi>lo){
                hi--;
            }
            array[lo]=array[hi];
            while(array[lo]<=key&&hi>lo){
                lo++;
            }
            array[hi]=array[lo];
        }
        array[hi]=key;
        return hi;
    }
    
    public static void swap(int a,int b){
        int temp=a;
        a=b;
        b=temp;
    }
    public static void sort(int[] array,int lo ,int hi){
        if(lo>=hi){
            return ;
        }
        int index=partition(array,lo,hi);
        sort(array,lo,index-1);
        sort(array,index+1,hi);
    }
}

輸出結果:

六.合並排序及其實現

1)合並排序代碼實現

package home;

public class MergeSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("合並排序算法:");
        int[] a = {12,20,5,16,15,1,30,45,23,9};
        int start = 0;
        int end = a.length-1;
        sort(a,start,end);
        for(int i = 0; i<a.length; i++){
             System.out.print(a[i]+" ");
         }
    }

    public static int[] sort(int[] a, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            sort(a, low, mid);
            sort(a, mid + 1, high);
            // 左右歸並
            merge(a, low, mid, high);
        }
        return a;
    }

    public static void merge(int[] a, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;
        int j = mid + 1;
        int k = 0;
        // 把較小的數先移到新數組中
        while (i <= mid && j <= high) {
            if (a[i] < a[j]) {
                temp[k++] = a[i++];
            } else {
                temp[k++] = a[j++];
            }
        }
        // 把左邊剩余的數移入數組
        while (i <= mid) {
            temp[k++] = a[i++];
        }
        // 把右邊邊剩余的數移入數組
        while (j <= high) {
            temp[k++] = a[j++];
        }
        // 把新數組中的數覆蓋nums數組
        for (int x = 0; x < temp.length; x++) {
            a[x + low] = temp[x];
        }
    }
}

2)控制台輸出結果:

七.計數排序及其實現

1)計數排序代碼實現

package home;

import java.util.Arrays;

public class CountingSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22 };
        int[] b1 = CountingSort(arr);
        System.out.println("基計數排序結果:");
        Arrays.stream(b1).forEach(item -> {
            System.out.print(item + " ");
        });
    }
    public static int[] CountingSort(int[] array) {
        if (array.length == 0) return array;
        int bias, min = array[0], max = array[0];
        for (int i = 1; i < array.length; i++) {
            if (array[i] > max)
                max = array[i];
            if (array[i] < min)
                min = array[i];
        }
        bias = 0 - min;
        int[] bucket = new int[max - min + 1];
        Arrays.fill(bucket, 0);
        for (int i = 0; i < array.length; i++) {
            bucket[array[i] + bias]++;
        }
        int index = 0, i = 0;
        while (index < array.length) {
            if (bucket[i] != 0) {
                array[index] = i - bias;
                bucket[i]--;
                index++;
            } else
                i++;
        }
        return array;
    }
}

2)控制台輸出結果

八.基數排序及其實現

1)基數排序

基數排序也是非比較的排序算法,對每一位進行排序,從最低位開始排序,復雜度為O(kn),為數組長度,k為數組中的數的最大的位數;

基數排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次類推,直到最高位。有時候有些屬性是有優先級順序的,先按低優先級排序,,再按高優先級排序。最后的次序就是高優先級高的在前,高優先級相同的低優先級高的在前。基數排序基於分別排序,分別收集,所以是穩定的

2)算法描述

     1.取得數組中的最大數,並取得位數。

     2. arr為原始數組,從最低位開始取每個位組成radix數組。

     3. 對radix進行計數排序(利用計數排序適用於小范圍數的特點)。

3)基數排序代碼實現

package home;

import java.util.ArrayList;
import java.util.Arrays;

public class RadixSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22 };
        int[] b1 = RadixSort(arr);
        System.out.println("基數排序結果:");
        Arrays.stream(b1).forEach(item -> {
            System.out.print(item + " ");
        });
    }
     public static int[] RadixSort(int[] array) {
            if (array == null || array.length < 2)
                return array;
            // 1.先算出最大數的位數;
            int max = array[0];
            for (int i = 1; i < array.length; i++) {
                max = Math.max(max, array[i]);
            }
            int maxDigit = 0;
            while (max != 0) {
                max /= 10;
                maxDigit++;
            }
            int mod = 10, div = 1;
            ArrayList<ArrayList<Integer>> bucketList = new ArrayList<ArrayList<Integer>>();
            for (int i = 0; i < 10; i++)
                bucketList.add(new ArrayList<Integer>());
            for (int i = 0; i < maxDigit; i++, mod *= 10, div *= 10) {
                for (int j = 0; j < array.length; j++) {
                    int num = (array[j] % mod) / div;
                    bucketList.get(num).add(array[j]);
                }
                int index = 0;
                for (int j = 0; j < bucketList.size(); j++) {
                    for (int k = 0; k < bucketList.get(j).size(); k++)
                        array[index++] = bucketList.get(j).get(k);
                    bucketList.get(j).clear();
                }
            }
            return array;
        }
}

4)控制台輸出結果

九.桶排序及其實現

 

1)桶排序代碼實現

package home;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;


public class BucketSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 1, 1, 2, 0, 9, 3, 12, 7, 8, 3, 4, 65, 22 };
        ArrayList <Integer> n = new ArrayList<Integer>();
        for(int i=0;i<arr.length;i++){
            n.add(arr[i]);
        }
        System.out.println("桶排序后的結果");
        ArrayList resultArr=BucketSort(n, arr.length);
        
        //遍歷方式1
        System.out.println("遍歷方式1:");
        Iterator it1 = resultArr.iterator();
        while(it1.hasNext()){
            System.out.print(it1.next()+" ");
        }
        
       //遍歷方式2
        System.out.println();
        System.out.println("遍歷方式2:");
        for(Iterator it2 = resultArr.iterator();it2.hasNext();){
            System.out.print(it2.next()+" ");
       }
        
      //遍歷方式3
        System.out.println();
        System.out.println("遍歷方式3:");
        for(int i = 0;i < resultArr.size(); i ++){
            System.out.print(resultArr.get(i)+" ");
        }
            
    }
    
    public static ArrayList<Integer> BucketSort(ArrayList<Integer> array, int bucketSize) {
        if (array == null || array.size() < 2)
            return array;
        int max = array.get(0), min = array.get(0);
        // 找到最大值最小值
        for (int i = 0; i < array.size(); i++) {
            if (array.get(i) > max)
                max = array.get(i);
            if (array.get(i) < min)
                min = array.get(i);
        }
        int bucketCount = (max - min) / bucketSize + 1;
        ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
        ArrayList<Integer> resultArr = new ArrayList<>();
        for (int i = 0; i < bucketCount; i++) {
            bucketArr.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < array.size(); i++) {
            bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
        }
        for (int i = 0; i < bucketCount; i++) {
            if (bucketSize == 1) { // 如果帶排序數組中有重復數字時  
                for (int j = 0; j < bucketArr.get(i).size(); j++)
                    resultArr.add(bucketArr.get(i).get(j));
            } else {
                if (bucketCount == 1)
                    bucketSize--;
                ArrayList<Integer> temp = BucketSort(bucketArr.get(i), bucketSize);
                for (int j = 0; j < temp.size(); j++)
                    resultArr.add(temp.get(j));
            }
        }
        return resultArr;
    }
}

2)控制台輸出結果

十.堆排序及其實現

(1)java實現堆排序

堆排序是一種樹形選擇排序方法,它的特點是:在排序的過程中,將array[0,...,n-1]看成是一顆完全二叉樹的順序存儲結構,利用完全二叉樹中雙親節點和孩子結點之間的內在關系,在當前無序區中選擇關鍵字最大(最小)的元素。

  1. 若array[0,...,n-1]表示一顆完全二叉樹的順序存儲模式,則雙親節點指針和孩子結點指針之間的內在關系如下:

任意一節點指針 i:父節點:i==0 ? null : (i-1)/2

                 左孩子:2*i + 1

                 右孩子:2*i + 2

  1. 堆的定義:n個關鍵字序列array[0,...,n-1],當且僅當滿足下列要求:(0 <= i <= (n-1)/2)

①        array[i] <= array[2*i + 1] 且 array[i] <= array[2*i + 2];稱為小根堆;

②       array[i] >= array[2*i + 1] 且 array[i] >= array[2*i + 2]; 稱為大根堆

  1. 建立大根堆:

n個節點的完全二叉樹array[0,...,n-1],最后一個節點n-1是第(n-1-1)/2個節點的孩子。對第(n-1-1)/2個節點為根的子樹調整,使該子樹稱為堆

對於大根堆,調整方法為:若【根節點的關鍵字】小於【左右子女中關鍵字較大者】,則交換。

之后向前依次對各節點((n-2)/2 - 1)~ 0為根的子樹進行調整,看該節點值是否大於其左右子節點的值,若不是,將左右子節點中較大值與之交換,交換后可能會破壞下一級堆,於是繼續采用上述方法構建下一級的堆,直到以該節點為根的子樹構成堆為止。

反復利用上述調整堆的方法建堆,直到根節點。

  1. 堆排序:(大根堆)

                   ①   將存放在array[0,...,n-1]中的n個元素建成初始堆;

                   ②   將堆頂元素與堆底元素進行交換,則序列的最大值即已放到正確的位置;

                   ③   但此時堆被破壞,將堆頂元素向下調整使其繼續保持大根堆的性質,再重復第②③步,直到堆中僅剩下一個元素為止。

空間復雜度:o(1);

時間復雜度:建堆:o(n),每次調整o(log n),故最好、最壞、平均情況下:o(n*logn);

穩定性:不穩定

2java代碼實現

package home;

public class HeapSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        HeapSort hs = new HeapSort();
        int[] array = { 87, 45, 78, 32, 17, 65, 53, 9, 122 };
        System.out.print("構建大根堆:");
        hs.toString(hs.buildMaxHeap(array));
        System.out.print("\n" + "刪除堆頂元素:");
        hs.toString(hs.deleteMax(array));
        System.out.print("\n" + "插入元素63:");
        hs.toString(hs.insertData(array, 63));
        System.out.print("\n" + "大根堆排序:");
        hs.toString(hs.heapSort(array));
    }

    // 刪除堆頂元素操作
    private int[] deleteMax(int[] array) {
        // TODO Auto-generated method stub
        // 將堆的最后一個元素與堆頂元素交換,堆底元素值設為-99999
        array[0] = array[array.length - 1];
        array[array.length - 1] = -99999;
        // 對此時的根節點進行向下調整
        adjustDownToUp(array, 0, array.length);
        return array;

    }

    // 將元素array[k]自下往上逐步調整樹形結構
    private void adjustDownToUp(int[] array, int k, int length) {
        // TODO Auto-generated method stub
        int temp = array[k];
        for (int i = 2 * k + 1; i < length - 1; i = 2 * i + 1) { // i為初始化為節點k的左孩子,沿節點較大的子節點向下調整
            if (i < length && array[i] < array[i + 1]) { // 取節點較大的子節點的下標
                i++; // 如果節點的右孩子>左孩子,則取右孩子節點的下標
            }
            if (temp >= array[i]) { // 根節點 >=左右子女中關鍵字較大者,調整結束
                break;
            } else { // 根節點 <左右子女中關鍵字較大者
                array[k] = array[i]; // 將左右子結點中較大值array[i]調整到雙親節點上
                k = i; // 【關鍵】修改k值,以便繼續向下調整
            }
        }
        array[k] = temp; // 被調整的結點的值放人最終位置
    }

    private void toString(int[] array) {
        // TODO Auto-generated method stub
        for (int i : array) {
            System.out.print(i + " ");
        }
    }

    // 構建大根堆:將array看成完全二叉樹的順序存儲結構
    private int[] buildMaxHeap(int[] array) {
        // TODO Auto-generated method stub
        // 從最后一個節點array.length-1的父節點(array.length-1-1)/2開始,直到根節點0,反復調整堆
        for (int i = (array.length - 2) / 2; i >= 0; i--) {
            adjustDownToUp(array, i, array.length);
        }
        return array;
    }

    // 插入操作:向大根堆array中插入數據data
    public int[] insertData(int[] array, int data) {
        // TODO Auto-generated method stub
        array[array.length - 1] = data; // 將新節點放在堆的末端
        int k = array.length - 1; // 需要調整的節點
        int parent = (k - 1) / 2; // 雙親節點
        while (parent >= 0 && data > array[parent]) {
            array[k] = array[parent]; // 雙親節點下調
            k = parent;
            if (parent != 0) {
                parent = (parent - 1) / 2; // 繼續向上比較
            } else { // 根節點已調整完畢,跳出循環
                break;
            }
        }
        array[k] = data; // 將插入的結點放到正確的位置
        return array;
    }

    // 堆排序
    public int[] heapSort(int[] array) {
        // TODO Auto-generated method stub
        array = buildMaxHeap(array); // 初始建堆,array[0]為第一趟值最大的元素
        for (int i = array.length - 1; i > 1; i--) {
            int temp = array[0]; // 將堆頂元素和堆低元素交換,即得到當前最大元素正確的排序位置
            array[0] = array[i];
            array[i] = temp;
            adjustDownToUp(array, 0, i); // 整理,將剩余的元素整理成堆
        }
        return array;
    }

}

3)控制台輸出結果

十一.二叉樹排序及有序集合

1)代碼實現

BinaryTree類:

package home;

public class BinaryTree {
    class Node { // 聲明一個節點類
        private Comparable data; // 節點的數據類型為Comparable
        private Node left; // 保存左子樹
        private Node right; // 保存右子樹

        public Node(Comparable data) { // 構造函數
            this.data = data;
        }

        public void addNode(Node newNode) {
            // 確定是放在左子樹還是右子樹
            if (newNode.data.compareTo(this.data) < 0) { // 新節點值小於當前節點
                if (this.left == null) {
                    this.left = newNode; // 左子樹為空的話,新節點設為左子樹
                } else {
                    this.left.addNode(newNode); // 否則繼續向下判斷
                }
            } else { // 新節點的值大於或等於當前節點
                if (this.right == null) {
                    this.right = newNode;
                } else {
                    this.right.addNode(newNode);
                }
            }
        }

        public void printNode() { // 采用中序遍歷
            if (this.left != null) { // 如果不為空先輸出左子樹
                this.left.printNode();
            }
            System.out.print(this.data + "\t"); // 輸出當前根節點
            if (this.right != null) { // 輸出右子樹
                this.right.printNode();
            }
        }
    }

    private Node root; // 表示根元素

    public void add(Comparable data) { // 向二叉樹中插入元素
        Node newNode = new Node(data);
        if (root == null) { // 沒有根節點
            root = newNode;
        } else {
            root.addNode(newNode); // 判斷放在左子樹還是右子樹
        }
    }

    public void print() {
        root.printNode(); // 根據根節點輸出
    }
}
BinaryTreeSort類:
package home;
public class BinaryTreeSort {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        BinaryTree bt = new BinaryTree();
        bt.add(3);
        bt.add(5);
        bt.add(4);
        bt.add(8);
        bt.add(7);
        bt.add(8);
        bt.add(1);
        bt.print();
    }
}

2)控制台輸出結果

十二.利用集合的4種排序排序方式

1)代碼實現

package home;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int[] b = { 1, 2, 4, 3, 6, 9, 7, 11, 13, 15, 
                18, 19, 23, 34, 56, 1000, 23, 78, 890, 908 };
       
        System.out.println("sort1()結果顯示:");
        Sort1(b);
        huanhang();
        
        System.out.println("sort2()結果顯示:");
        Sort2(b);
        huanhang();
        
        System.out.println("sort3()結果顯示:");
        Sort3(b);
        huanhang();
        
        System.out.println("sort4()結果顯示:");
        sort4(b);
        huanhang();

    }
        //換兩次行
    private static void huanhang() {
        // TODO Auto-generated method stub
        for(int i=0;i<=2;i++){
            System.out.println();
        }
    }

    private static void sort4(int[] b) {
        // TODO Auto-generated method stub
        List<Integer> lists = new ArrayList<Integer>();
        for (int i = 0; i < b.length; i++) {
            lists.add(b[i]);
        }

        // 排序,直接調用sort方法排序,排序方式是自然排序,即升序排序
        System.out.println("利用collections.sort()方法給list排序(默認為升序):");
        Collections.sort(lists);
        
        // 遍歷
        for(int i:lists){
            System.out.print(i+" ");
        }    
        System.out.println();
        System.out.println("利用collections.sort()方法給list降序排序"
                + "(先升序后用collections.reverse()反轉):");
        System.out.print("=============");
        System.out.println("java8使用lamda表達式(forEach方法)對集合進行遍歷:");
        Collections.reverse(lists);
        
        //java8使用lamda表達式(forEach方法)對集合進行遍歷
        lists.forEach(obj -> System.out.print(obj+"  "));
        
        //java8使用lamda表達式Iterator的forEachRemaining方法)對集合進行遍歷
        System.out.println("");
        System.out.print("=============");
        System.out.println("java8使用lamda表達式Iterator的forEachRemaining方法)"
                + "對集合進行遍歷:");
        Iterator<Integer> it =lists.iterator();
        it.forEachRemaining(obj->System.out.print(obj+"  "));
    }
     
    private static void Sort3(int[] b) {
        // TODO Auto-generated method stub
        // int數組轉化為Integer數組
        int n = b.length;
        Integer[] iarr = new Integer[n];
        for (int i = 0; i < n; i++) {
            iarr[i] = new Integer(b[i]);
        }

        List<Integer> resultList = new ArrayList<>(iarr.length);
        Collections.addAll(resultList, iarr);

        
        System.out.println("利用collections給list排序:");
        for (int i : resultList) {
            System.out.print(i + " ");
        }

    }

    private static void Sort2(int[] b) {
        // TODO Auto-generated method stub
        @SuppressWarnings("unused")

        TreeSet<Integer> ts = new <Integer>TreeSet<Integer>();
        for (int i = 0; i < b.length; i++) {
            ts.add(b[i]);
        }

        System.out.println("利用TreeSet方集合排序(會去掉重復的元素):");
        Iterator<Integer> it = ts.iterator();
        while (it.hasNext()) {
            System.out.print(it.next() + " ");
        }

    }

    private static void Sort1(int[] b) {
        // TODO Auto-generated method stub
        Arrays.sort(b);
        System.out.println("利用Arrays.sort()方法排序:");
        Arrays.stream(b).forEach(item -> {
            System.out.print(item + " ");
        });
        System.out.println();
    }
}

                 

2)控制台輸出結果

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM