經典排序算法(Java實現)

如下程序均將數據封裝於DataWrap數據包裝類中,以下所示:數組

class DataWrap implements Comparable<DataWrap>
      {
         int data;
         String flag;
         public DataWrap(int data,String flag)
         {
             this.data = data;
             this.flag = flag;
         }
         //重寫compareTo方法
         public int compareTo(DataWrap other)
         {
             return this.data > other.data ? 1 : (this.data == other.data ? 0 : -1);
         }
         public String toString()
         {
             return this.data + this.flag;
         }
     }

 

1、選擇排序ui

一、直接選擇排序this

  數組分紅有序區和無序區,初始時整個數組都是無序區,而後每次從無序區選一個最小的元素直接放到有序區的最後,直到整個數組變有序區。spa

1 public static void directSelectSort(DataWrap[] dw)
 2     {
 3         int n = dw.length;
 4         for(int i = 0;i < n-1;i++)
 5         {
 6             int minIndex = i;  
 7             for(int j = i+1;j < n;j++)
 8             {
 9                 if(dw[minIndex].compareTo(dw[j]) > 0)
10                 {
11                     minIndex = j;  //minIndex爲每趟比較重最小數的索引
12                 }
13             }
14             swap(dw,minIndex,i);
15             System.out.println("直接選擇排序中的元素:" + Arrays.toString(dw));
16         }
17         
18     }

二、堆排序code

  1)二叉堆排序

    二叉堆是徹底二叉樹或者是近似徹底二叉樹。遞歸

    父結點的鍵值老是大於或等於(小於或等於)任何一個子節點的鍵值。索引

    每一個結點的左子樹和右子樹都是一個二叉堆(都是最大堆或最小堆)。it

      當父結點的鍵值老是大於或等於任何一個子節點的鍵值時爲最大堆。當父結點的鍵值老是小於或等於任何一個子節點的鍵值時爲最小堆。io

  2)堆的存儲

    通常都用數組來表示堆,i結點的父結點下標就爲(i – 1) / 2。它的左右子結點下標分別爲2 * i + 1和2 * i + 2。如第0個結點左右子結點下標分別爲1和2。

  3)堆排序原理(以最小堆爲例)

    堆排序是先創建一個最小堆,而後第一次將A[0]與A[n - 1]交換,再對A[0…n-2]從新恢復最小堆。第二次將A[0]與A[n – 2]交換,再對A[0,…,n - 3]從新恢復最小堆,重複這樣的操做直到A[0]與A[1]交換。因爲每次都是將最小的數據併入到後面的有序區間,故操做完成後整個數組就有序(爲降序)了。

創建最小堆就是先從最後一個非葉子節點(即n/2-1節點)開始,節點依次往前就行,直到第二個節點。對於每一個節點,先比較其左右節點選出較小的節點,而後將較小的節點與父節點進行比較。若是父節點比最小的子節點還小的話則不須要調整,不然的話將較小的子節點做爲新的父節點,將原先的父節點與其子節點的子節點中較小的進行比較,直到該父節點找到可以插入的位置或者是到達堆的結束。

  4)代碼實現

1 public class HeapSort 
 2 {
 3     /**
 4      * 從某一節點向下調整大小  
 5      * @param dw 待排序數據包
 6      * @param i     開始向下調整的堆索引
 7      * @param n  所調整堆數據的大小
 8      */
 9     public static void MinHeapFixDown(DataWrap[] dw,int i,int n)
10     {
11         int j;
12         DataWrap temp;
13         j = 2 * i +1;
14         temp = dw[i];
15         while(j < n)
16         {
17             if(j+1 < n && dw[j+1].compareTo(dw[j]) < 0)
18             { //找出左右子節點中較小的
19                 j++;
20             }
21             if(temp.compareTo(dw[j]) <= 0)
22             {  //將父節點與子節點進行比較
23                 break;
24             }
25             dw[i] = dw[j];  //將較小的子節點上移
26             i = j;
27             j = 2 * i +1;
28         }
29         dw[i] = temp; 
30     }
31     //構建最小堆並進行堆排序
32     public static void heapSort(DataWrap[] dw)
33     {
34         int n = dw.length;
35         //構建最小堆
36         for(int i = n/2-1;i >= 0;i--)
37         {
38             HeapSort.MinHeapFixDown(dw, i, n);
39         }
40         //堆排序
41         for(int i = n-1;i >=1;i--)
42         {  
43             swap(dw,0,i);   //每次將第n-1,n-2,...1個元素與dw[0]交換後,將最後一個元素從堆中排除
44             MinHeapFixDown(dw, 0, i); //將每次交換後-1的堆從dw[0]開始,調整爲新的最小堆
45         }
46     }
47     
48     //交換DataWrap數組中i,j兩數值
49     public static void swap(DataWrap[] dw,int i,int j)
50     {
51         DataWrap temp;
52         temp = dw[i];
53         dw[i] = dw[j];
54         dw[j] = temp;
55     } 
56     
57     public static void main(String[] args)
58     {
59         DataWrap[] dw = {new DataWrap(25,""),new DataWrap(42,""),new DataWrap(36,""),new DataWrap(8,""),new DataWrap(78,""),new DataWrap(99,"")};
60         System.out.println("待排序數據爲:" + Arrays.toString(dw));
61         HeapSort.heapSort(dw);
62         System.out.println("排序後數據爲:" + Arrays.toString(dw));        
63     }
64 }

2、交換排序

一、冒泡排序

  1.比較相鄰的先後二個數據,若是前面數據大於後面的數據,就將二個數據交換。

  2.這樣對數組的第0個數據到N-1個數據進行一次遍歷後,最大的一個數據就「沉」到數組第N-1個位置。

  3.N=N-1,若是N不爲0就重複前面二步,不然排序完成。

1 public static void bubbleSort(DataWrap[] dw)
 2     {
 3         int n = dw.length;
 4         boolean flag;//設置標誌位,若發生未交換的狀況,說明已經有序,退出循環便可
 5         for(int i = n-1;i > 0 ;i--)
 6         {
 7             flag = false;
 8             for(int j = 0;j < i;j++)
 9             {
10                 if(dw[j].compareTo(dw[j+1]) > 0)
11                 {
12                     swap(dw,j+1,j);
13                     flag = true;
14                 }
15             }
16             if(!flag)
17             {
18                 break;
19             }
20             System.out.println("排序中順序:" + Arrays.toString(dw));
21         }
22     }

二、快速排序

  快速選擇排序主要思路是:

  「挖坑填數+分治法」,首先令i =L; j = R; 將a[i]挖出造成第一個坑,稱a[i]爲基準數。而後j--由後向前找比基準數小的數,找到後挖出此數填入前一個坑a[i]中,再i++由前

向後找比基準數大的數,找到後也挖出此數填到前一個坑a[j]中。重複進行這種「挖坑填數」直到i==j。再將基準數填入a[i]中,這樣i以前的數都比基準數小,i以後的數都比基準數

大。所以將數組分紅二部分再分別重複上述步驟就完成了排序。

public class QuickSort {

  static int partition(int[] data, int left, int high) {
    int midData = data[left];
    while (left < high) {
      while (left < high && midData < data[high])
        high--;
      data[left] = data[high];
      while (left < high && midData >= data[left])
        left++;
      data[high] = data[left];
    }
    data[left] = midData;
    return left;
  }

  /**
   * 快速排序
   * 
   * @param data
   * @param left
   * @param high
   */
  static void quick_sort(int[] data, int left, int high) {
    int loc = 0;
    if (left < high) {
      loc = partition(data, left, high);
      quick_sort(data, left, loc - 1);
      quick_sort(data, loc + 1, high);
    }
  }

  public static void main(String[] args) {
    int[] data = {6, 2, 4, 8, 5, 9};
    quick_sort(data, 0, data.length - 1);
    System.out.print("排序後數據爲:" + Arrays.toString(data));
  }



}

3、插入排序

一、直接插入排序

  每次將一個待排序的記錄,按其關鍵字大小插入到前面已經排好序的子序列中的適當位置,直到所有記錄插入完成爲止。

public static void directInsertSort(DataWrap[] dw,int n)
 2     {
 3         for(int i = 1;i < n;i++)
 4         {
 5             if(dw[i].compareTo(dw[i-1]) < 0)
 6             {
 7                 DataWrap temp = dw[i];
 8                 int j;
 9                 for(j = i-1;j >= 0 && dw[j].compareTo(temp) > 0;j--)
10                 {
11                     dw[j+1] = dw[j];
12                 }
13                 dw[j+1] = temp;
14             }
15         }
16     }

二、希爾排序(Shell排序、縮小增量排序)

  ‍先將整個待排元素序列分割成若干個子序列(由相隔某個「增量」的元素組成的)分別進行直接插入排序,而後依次縮減增量再進行排序,待整個序列中的元素基本有序(增量足夠小)時,再對全體元素進行一次直接插入排序。因爲希爾排序是對相隔若干距離的數據進行直接插入排序,所以能夠形象的稱希爾排序爲「跳着插」‍

public static void directInsertSort(DataWrap[] dw,int n)
 2     {
 3         for(int i = 1;i < n;i++)
 4         {
 5             if(dw[i].compareTo(dw[i-1]) < 0)
 6             {
 7                 DataWrap temp = dw[i];
 8                 int j;
 9                 for(j = i-1;j >= 0 && dw[j].compareTo(temp) > 0;j--)
10                 {
11                     dw[j+1] = dw[j];
12                 }
13                 dw[j+1] = temp;
14             }
15         }
16     }

4、歸併排序

  當一個數組左邊和右邊都有序時,將兩邊合併就完成了排序,而要使兩邊都有序,則須要用遞歸。先遞歸下去,再合併上來,就是歸併排序。

1 public class MergeSort
 2 {
 3     
 4     public static void mergeSort(int[] data)
 5     {
 6         int n = data.length;
 7         sort(data, 0, n-1);//歸併排序
 8     }
 9     
10     public static void sort(int[] data,int left,int right)
11     {
12         if(left <right)
13         {
14             int center = (left + right)/2;//中間索引
15             sort(data, left, center);//堆左邊數組進行遞歸
16             sort(data, center+1, right);//堆右邊數組進行遞歸
17             merge(data, left, center, right);//合併
18         }
19     }
20     
21     public static void merge(int[] data,int left,int center,int right)
22     {
23         int[] array = new int[data.length];//定義臨時數組
24         int mid = center+1;
25         int k = left;//臨時數組索引
26         int temp = left;
27         while(left <= center && mid <= right)
28         {
29             if(data[left] < data[mid])
30                 array[k++] = data[left++];
31             else
32                 array[k++] = data[mid++];
33         }
34         while(left <= center)
35             array[k++] = data[left++];
36         while(mid <= right)
37             array[k++] = data[mid++];
38         while(temp <= right)
39             data[temp] = array[temp++];
40     }
41     
42     public static void main(String[] args)
43     {
44         int[] data = {2,27,56,8,24,12,99,0,56};
45         MergeSort.mergeSort(data);
46         for(int i:data)
47         {
48             System.out.print(i + ",");
49         }
50     }
51 }
相關文章
相關標籤/搜索