- import java.util.Arrays;
- /**
- * 各種排序方法
- *
- * @author zhezi
- *
- */
- public class Sort {
- /**
- * 1.直接插入排序,asc
- */
- public void insertSort(int[] arr, int low, int high) {
- for (int i = low + 1; i < high; i++) {
- if (arr[i] < arr[i - 1]) { // i < i-1
- int temp = arr[i];
- arr[i] = arr[i - 1]; // i-1 後移
- int j = i - 2;
- for (; j >= low && (temp < arr[j]); j--) { // i 與
- // i-1之前的元素進行比較(找出最小值)
- arr[j + 1] = arr[j]; // i-2 後移到 i-1
- }
- arr[j + 1] = temp; // i插入到合適位置
- }
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /**
- * 2.折半插入排序(二分查找)
- */
- public void binInsertSort(int[] arr, int low, int high) {
- for (int i = low + 1; i < high; i++) {
- int temp = arr[i];
- int hi = i - 1;
- int lo = low; // 設置初始期間
- while (lo <= hi) {
- int mid = (lo + hi) / 2;
- if (temp < arr[mid]) {
- hi = mid - 1;
- } else {
- lo = mid + 1;
- }
- }
- for (int j = i - 1; j > hi; j--) { // 移動元素
- arr[j + 1] = arr[j];
- }
- arr[hi + 1] = temp; // 插入元素
- }
- // 輸出
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /**
- * 3.希爾排序
- */
- int[] delta = { 3, 2, 1 };
- /** 步長序列,步長值必須互質,且最後一個步長值必須爲1 **/
- public void shellSort(int[] arr, int low, int high, int[] delta) {
- for (int i = 0; i < delta.length; i++) {
- shellInsert(arr, low, high, delta[i]);
- }
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- public void shellInsert(int[] arr, int low, int high, int deltaK) {
- for (int i = low + deltaK; i < high; i++) {
- if (arr[i] < arr[i - deltaK]) {
- int temp = arr[i];
- int j = i - deltaK;
- for (; j >= low && temp < arr[j]; j = j - deltaK) {
- arr[j + deltaK] = arr[j];
- }
- arr[j + deltaK] = temp;
- }
- }
- }
- /**
- * 4.冒泡排序 --兩兩位置相比較,找到最大的,放到最後
- */
- public void bubbleSort(int[] arr, int low, int high) {
- for (int i = low; i < high; i++) { // 循環次數
- for (int j = low; j < high - i - 1; j++) { // 兩兩位置相比較,找出最大的
- if (arr[j] > arr[j + 1]) {
- int temp = arr[j];
- arr[j] = arr[j + 1];
- arr[j + 1] = temp;
- }
- }
- }
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /**
- * 5.快速排序 ---找到樞軸元素,分爲兩個子序列,左邊都比樞軸小,右邊都比樞軸大,再對子序列排序
- */
- public void quickSort(int[] arr, int low, int high) {
- if (low < high) {
- int pa = partition(arr, low, high);
- quickSort(arr, low, pa - 1);
- quickSort(arr, pa + 1, high);
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /** 將序列劃分爲兩列,返回樞軸元素的位置 **/
- public int partition(int[] arr, int low, int high) {
- int pivot = arr[low]; // 使用arr[low]作爲樞軸元素
- while (low < high) { // 從兩端向內掃描
- while (low < high && (arr[high] >= pivot)) {
- high--;
- }
- arr[low] = arr[high]; // 將小於pivot的元素移向低端
- while (low < high && (arr[low] <= pivot)) {
- low++;
- }
- arr[high] = arr[low]; // 將大於pivot的元素移向高端
- }
- arr[low] = pivot;
- return low;
- }
- /**
- * 6.簡單選擇排序 ---每一次遍歷,找到最小值放到前面
- */
- public void selectSort(int[] arr, int low, int high) {
- for (int i = low; i < high; i++) {
- int min = i;
- for (int j = min + 1; j < high; j++) {
- if (arr[j] < arr[min]) {
- min = j;
- }
- }
- if (i != min) {
- int temp = arr[i];
- arr[i] = arr[min];
- arr[min] = temp;
- }
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /**
- * 7.堆排序
- */
- public void heapSort(int[] arr) {
- int n = arr.length;
- for (int i = n / 2; i > 0; i--) { // 初始化建堆
- heapAdjust(arr, i - 1, n);
- }
- for (int i = n - 2; i >= 0; i--) { // 不斷輸出堆頂元素並調整新堆
- int temp = arr[i + 1]; // 交換堆頂元素與堆底元素
- arr[i + 1] = arr[0];
- arr[0] = temp;
- heapAdjust(arr, 0, i + 1); // 調整
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /** 調整爲小頂堆 **/
- private void heapAdjust(int[] arr, int low, int high) {
- int temp = arr[low]; // 頂端元素
- int j = low * 2 + 1; // 左邊子元素
- while (j <= high - 1) { // 從第一個子元素逐漸向下篩選
- if (j < high - 1 && arr[j] < arr[j + 1]) { // 找到最大的子元素
- j++;
- }
- if (temp >= arr[j]) { // 若頂端元素temp比孩子元素都小,插入到頂端
- break;
- }
- arr[(j - 1) / 2] = arr[j];
- j = 2 * j + 1;
- }
- arr[(j - 1) / 2] = temp;
- }
- /**
- * 8.歸併排序
- */
- public void mergeSort(int[] arr, int low, int high) {
- if (low < high) {
- mergeSort(arr, low, (high + low) / 2);
- mergeSort(arr, (high + low) / 2 + 1, high);
- merge(arr, low, (low + high) / 2 + 1, high);
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- System.out.println();
- }
- /** 歸併操作將基本單位歸併成整個有序的數組 **/
- private void merge(int[] list, int left, int right, int last) {
- int[] temp = new int[list.length];// 臨時數組
- int j = 0;
- int lowIndex = left;
- int mid = right - 1;
- int n = last - lowIndex + 1;
- while (left <= mid && right <= last) {
- if (list[left] < list[right]) {
- temp[j++] = list[left++];
- } else {
- temp[j++] = list[right++];
- }
- }
- while (left <= mid) {
- temp[j++] = list[left++];
- }
- while (right <= last) {
- temp[j++] = list[right++];
- }
- for (j = 0; j < n; j++) {
- list[lowIndex + j] = temp[j];
- }
- }
- /**
- *9.計數排序 ---適用於待排序的數組元素最大值已經給定的情況下。
- * b[] 存放正確排序的結果
- * c[] 存放每個元素在序列中出現的次數
- * k 爲序列中的最大值
- */
- public void countSort(int[] arr, int[] b, int k) {
- int[] c = new int[k + 1];
- for (int i = 0; i < k; i++) {
- c[i] = 0;
- }
- for (int i = 0; i < arr.length; i++) {
- c[arr[i]]++; //存放a中元素等於i的元素個數
- }
- for (int i = 1; i <= k; i++) {
- c[i] += c[i - 1]; //存放a中元素<=i的元素個數
- }
- for (int i = arr.length - 1; i >= 0; i--) { //把a中每個元素放入b中正確的位置.
- b[c[arr[i]] - 1] = arr[i];
- c[arr[i]]--; //a中如果有元素的值相等此句是必須的.
- }
- }
- /**返回序列中的最大值**/
- public static int getMaxNumber(int[] a) {
- int max = 0;
- for (int i = 0; i < a.length; i++) {
- if (max < a[i]) {
- max = a[i];
- }
- }
- return max;
- }
- /**
- * 10.基數排序 ---將所有待比較數值(正整數)統一爲同樣的數位長度,數位較短的數前面補零. 然後,從最低位開始, 依次進行一次排序.
- * radix 設定的基數
- * d 數組中最多位數
- */
- public void radixSort(int[] arr,int radix,int d){
- //定義一個臨時數組大小和data數組相等
- int[] temp = new int[arr.length];
- //定義一個位計數器,用來存放當前位的元素有多少個
- int[] bucket = new int[radix];
- int rate = 1;
- for (int i = 0; i < d; i++) {
- //將data數組中的各個元素複製到temp數組中
- System.arraycopy(arr, 0, temp, 0, arr.length);
- //將bucket數組的各個元素重置0
- Arrays.fill(bucket, 0);
- for (int j = 0; j < arr.length; j++) {
- int index = (temp[j] / rate) % radix;
- bucket[index] += 1;
- }
- for (int j = 1; j < bucket.length; j++) {
- bucket[j] = bucket[j] + bucket[j - 1];
- }
- for (int j = arr.length - 1; j >= 0; j--) {
- int index = (temp[j] / rate) % radix;
- arr[--bucket[index]] = temp[j];
- }
- //接着rate乘以10並對十位進行相應排序
- rate *= radix;
- }
- /** 輸出 **/
- for (int k = 0; k < arr.length; k++) {
- System.out.print(arr[k] + ",");
- }
- }
- public static void main(String[] args) {
- int[] arr = { 26, 53, 48, 11, 13, 48, 32, 15 };
- /** 待排序數組 **/
- int low = 0;
- /** 排序期間的起始位 **/
- int high = arr.length;
- /** 排序期間的末位 **/
- int[] delta = { 5, 3, 1 };
- Sort s = new Sort();
- // s.insertSort(arr, low, high);
- // s.binInsertSort(arr, low, high);
- // s.shellSort(arr, low, high, delta);
- // s.bubbleSort(arr, low, high);
- // s.quickSort(arr, low, high-1);
- // s.selectSort(arr, low, high);
- // s.heapSort(arr);
- //s.mergeSort(arr, low, high - 1);
- //int[] b = new int[arr.length];
- //s.countSort(arr, b, Sort.getMaxNumber(arr));
- /** 輸出 **/
- // for (int k = 0; k < b.length; k++) {
- // System.out.print(b[k] + ",");
- // }
- s.radixSort(arr, 10, 2);
- }
- }