1. 程式人生 > >常用的8個排序演算法,親測排序

常用的8個排序演算法,親測排序

package com.quanran;

import java.util.Random;

public class Sort {
	/**
	 * <p>
	 * Discription:[下面的演算法順序在前的比後面的快,但並不絕對。
	 * 因為我最試的是陣列長度從0到805000,如果測試資料長度接近805000,
	 * 則和我說的排序貼合]
	 * </p>
	 * Created on 2018年9月18日 下午3:53:11
	 * 
	 * @param args
	 *            void
	 * @author:[全冉]
	 */
	public static void main(String[] args) {
 
		// 第一位(最快的):歸併排序
		int[] array = getIntArray();
		long startNs = System.nanoTime();
		mergeSort(array, 0, array.length - 1, new int[array.length]);
		long endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",歸併排序 : "/*Arrays.toString(array)*/);
 
		// 第二位:希爾排序
		array = getIntArray();
		startNs = System.nanoTime();
		shellSort(array, 0, array.length);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",希爾排序 : "/*Arrays.toString(array)*/);
				
		// 第三位:快速排序
		array = getIntArray();
		startNs = System.nanoTime();
		quickSort(array, 0, array.length - 1);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",快速排序 : "/*Arrays.toString(array)*/);
		
		// 第四位:折半插入排序
		array = getIntArray();
		startNs = System.nanoTime();
		binaryInsertSort(array);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",折半插入排序 : "/*Arrays.toString(array)*/);
		
		// 第五位:直接插入排序
		array = getIntArray();
		startNs = System.nanoTime();
		directInsertSort(array);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",直接插入排序 : "/*Arrays.toString(array)*/);
		
		// 第六位:直接選擇排序
		array = getIntArray();
		startNs = System.nanoTime();
		directChooseSort(array);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",直接選擇排序 : "/*Arrays.toString(array)*/);
				
		// 第七位:堆排序
		array = getIntArray();
		startNs = System.nanoTime();
		heapSort(array, 0, array.length);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",堆排序 : "/*Arrays.toString(array)*/);
 
		// 第八位(最慢的):氣泡排序
		array = getIntArray();
		startNs = System.nanoTime();
		bubbleSort(array);
		endNs = System.nanoTime();
		System.out.println("耗時 :" + (endNs - startNs) + ",氣泡排序 : "/*Arrays.toString(array)*/);
		
	}
 
	/**
	 * 直接選擇排序
	 */
	private static void directChooseSort(int[] array) {
		for (int i = 0; i < array.length; i++) {
			int index = i;
			for (int j = i + 1; j < array.length; j++) {
				if (array[index] > array[j]) {
					index = j;
				}
			}
			if (i != index) {
				int temp = array[i];
				array[i] = array[index];
				array[index] = temp;
			}
		}
	}
 
	/**
	 * 堆排序
	 */
	private static void heapSort(int[] array, int start, int len) {
		int pos = (len - 1) / 2;
		for (int i = pos; i >= 0; i--) {
			int tmp = array[start + i];
			int index = i * 2 + 1;
			while (index < len) {
				if (index + 1 < len
						&& array[start + index] < array[start + index + 1]) // 從小到大
				{
					index += 1;
				}
				if (tmp < array[start + index]) // 從小到大
				{
					array[start + i] = array[start + index];
					i = index;
					index = i * 2 + 1;
				} else {
					break;
				}
			}
			array[start + i] = tmp;
		}
		for (int i = 0; i < len; i++) {
			int temp = array[start];
			array[start] = array[start + len - 1 - i];
			array[start + len - 1 - i] = temp;
			// 再一次
			int post = 0;
			int tmp = array[start + post];
			int index = 2 * post + 1;
			while (index < len - 1 - i) {
				if (index + 1 < len - 1 - i
						&& array[start + index] < array[start + index + 1]) // 從小到大
				{
					index += 1;
				}
				if (tmp < array[start + index]) // 從小到大
				{
					array[start + post] = array[start + index];
					post = index;
					index = post * 2 + 1;
				} else {
					break;
				}
			}
			array[start + post] = tmp;
		}
	}
 
	/**
	 * 氣泡排序
	 */
	private static void bubbleSort(int[] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = i + 1; j < array.length; j++) {
				if (array[i] > array[j]) {
					int temp = array[i];
					array[i] = array[j];
					array[j] = temp;
				}
			}
		}
	}
 
	/**
	 * 快速排序
	 */
	private static void quickSort(int[] array, int start, int end) {
		if (start < end) {
			int key = array[start];
			int i = start;
			for (int j = start + 1; j < end + 1; j++) {
				if (key > array[j]) {
					int temp = array[j];
					array[j] = array[i + 1];
					array[i + 1] = temp;
					i++;
				}
			}
			array[start] = array[i];
			array[i] = key;
			quickSort(array, start, i - 1);
			quickSort(array, i + 1, end);
		}
	}
 
	/**
	 * 直接插入排序
	 */
	private static void directInsertSort(int[] array) {
		for (int i = 1; i < array.length; i++) {
			int j;
			int temp = array[i];
			for (j = i; j > 0; j--) {
				if (array[j - 1] > temp) {
					array[j] = array[j - 1];
				} else {
					break;
				}
			}
			array[j] = temp;
		}
	}
 
	/**
	 * 折半插入排序
	 */
	private static void binaryInsertSort(int[] array) {
		for (int i = 1; i < array.length; i++) {
			// if (array[i] > array[i - 1]) // 從大到小
			if (array[i] < array[i - 1]) // 從小到大
			{
				int tmp = array[i];
				int low = 0;
				int high = i - 1;
				while (low <= high) {
					int mid = (low + high) >>> 1;
					// if (array[mid] > tmp) // 從大到小
					if (array[mid] < tmp)// 從小到大
					{
						low = mid + 1;
					} else {
						high = mid - 1;
					}
				}
				for (int j = i; j > low; j--) {
					array[j] = array[j - 1];
				}
				array[low] = tmp;
			}
		}
	}
 
	/**
	 * 希爾排序
	 */
	private static void shellSort(int[] array, int start, int len) {
		int power = 1;
		while ((power + 1) * 2 < len) {
			power = (power + 1) * 2 - 1;
		}
		for (int k = power; k >= 1; k = (k + 1) / 2 - 1) {
			for (int i = 0; i < k; i++) {
				if (len - i <= 1) {
					break;
				}
				int tmp;
				for (int j = start + i + k; j < start + len; j += k) {
					tmp = array[j];
					int m = j;
					for (; m > start + i; m -= k) {
						if (array[m - k] > tmp) // 從小到大
						{
							array[m] = array[m - k];
						} else {
							break;
						}
					}
					array[m] = tmp;
				}
			}
		}
	}
 
	/**
	 * 歸併排序
	 */
	private static void mergeSort(int[] array, int start, int end,
			int[] tempArray) {
		if (end <= start) {
			return;
		}
		int middle = (start + end) / 2;
		mergeSort(array, start, middle, tempArray);
		mergeSort(array, middle + 1, end, tempArray);
		int k = 0, leftIndex = 0, rightIndex = end - start;
		System.arraycopy(array, start, tempArray, 0, middle - start + 1);
		for (int i = 0; i < end - middle; i++) {
			tempArray[end - start - i] = array[middle + i + 1];
		}
		while (k < end - start + 1) {
			if (tempArray[rightIndex] > tempArray[leftIndex]) // 從小到大
			{
				array[k + start] = tempArray[leftIndex++];
			} else {
				array[k + start] = tempArray[rightIndex--];
			}
			k++;
		}
	}
 
	/**
	 * 獲取int陣列,長度為size
	 */
	private static int[] getIntArray() {
		int size = 805000;// 要排序的資料長度
		int[] arr3 = new int[size];
		int[] firstNums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int[] otherNums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int digitsNum = 0;// arr3裡的當前數的位數
		int temNum = 0;// arr3裡的當前數裡某一位的值
		Random random = new Random();
		StringBuffer bf = new StringBuffer();
		for (int i = 0; i < size; i++) {
			// 生成當前數的總位數
			digitsNum = random.nextInt(9);// 生成區間 [0,8]
											// 中隨機值,限制每個數的位數在9位數(包括9位數)之內
			digitsNum = firstNums[digitsNum];
			for (int j = 0; j < digitsNum; j++) {
				// 生成當前數第一位的值
				if (j == 0) {
					temNum = random.nextInt(9);// 生成區間 [0,8] 中隨機值
					temNum = firstNums[temNum];
					bf.append(temNum);
				} else {
					temNum = random.nextInt(10);// 生成區間 [0,9] 中隨機值
					temNum = otherNums[temNum];
					bf.append(temNum);
				}
			}
			arr3[i] = Integer.valueOf(bf.toString());
			bf.delete(0, bf.length());// 清空bf內容
		}
		return arr3;
	}
}