java十大排序算法

常见排序算法

package com.daojia.dop.broker.repository.entity;

import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.SecureRandom;


/**
 * 十大经典排序
 * 参考:https://www.runoob.com/w3cnote/radix-sort.html
 */
public class SortDemo {

	private static final Logger logger = LoggerFactory.getLogger(SortDemo.class);

	public static void main(String[] args) {
		logger.info("=================start main=====================");
		int n = 10;
		int[] array = new int[n];
		SecureRandom secureRandom = new SecureRandom();
		for (int i = 0; i < array.length; i++) {
			array[i] = secureRandom.nextInt(2*n);
		}
		logger.info("=================start sort=======================");
		logger.info(JSONObject.toJSONString(array));
		//排序
		int[] array1 = array.clone();
		bubbleSort(array1);

		int[] array2 = array.clone();
		quickSort(array2);

		int[] array3 = array.clone();
		heapSort(array3);

		int[] array4 = array.clone();
		returnSort(array4);

		int[] array5 = array.clone();
		insertSort(array5);


		int[] array6 = array.clone();
		choiceSort(array6);

		int[] array8 = array.clone();
		hillSort(array8);

		int[] array9 = array.clone();
		bucketSort(array9);

		int[] array7 = array.clone();
		countSort(array7);




		logger.info(JSONObject.toJSONString(array));
		logger.info(JSONObject.toJSONString(array1));
		logger.info(JSONObject.toJSONString(array2));
		logger.info(JSONObject.toJSONString(array3));
		logger.info(JSONObject.toJSONString(array4));
		logger.info(JSONObject.toJSONString(array5));
		logger.info(JSONObject.toJSONString(array5));
		logger.info(JSONObject.toJSONString(array7));
		logger.info(JSONObject.toJSONString(array8));
		logger.info(JSONObject.toJSONString(array9));

	}

	/**
	 * @param n 冒泡
	 *          如果某一次冒泡没有发生交换则跳出循环
	 *          时间复杂度O(n^2) 空间复杂度O(1)
	 */
	public static void bubbleSort(int[] n) {
		Long start = System.currentTimeMillis();
		for (int i = 0; i < n.length - 1; i++) {
			boolean flag = true;
			for (int j = 0; j < n.length - i - 1; j++) {
				if (n[j] > n[j + 1]) {
					swap(n, j, j + 1);
					flag = false;
				}
			}
			if (flag) {
				break;
			}
		}
		logger.info("runTime for bubbleSort ={}", System.currentTimeMillis() - start);
	}

	public static void swap(int[] n, int i, int j) {
		int tem = n[i];
		n[i] = n[j];
		n[j] = tem;
	}

	/**
	 * @param n 快排
	 *          

* 左右两个指针,取排序开始位为基准值,右指针遍历比基准值小的位置跟左指针交换数据, * 左指针遍历比基准值大的值跟右指针交换位置,最后左右指针重合将基准值放到重合位置 * 时间复杂度O(nlogn) */ public static void quickSort(int[] n) { Long start = System.currentTimeMillis(); quick(n, 0, n.length - 1); logger.info("runTime for quickSort ={}", System.currentTimeMillis() - start); } public static void quick(int[] n, int start, int end) { int left = start; int key = n[start]; int right = end; while (left < right) { //必须要又=号否则两数相等死循环 while (left < right && n[right] >= key) { right--; } swap(n, right, left); while (left < right && n[left] <= key) { left++; } swap(n, left, right); } n[left] = key; if (left + 1 < end) { quick(n, left + 1, end); } if (left - 1 > start) { quick(n, start, left - 1); } } /** * @param n 堆排 * 堆的结构是完全二叉树,可以用数组存 * 构建最大堆->堆排序 * 时间复杂度O(nlogn) */ public static void heapSort(int[] n) { Long start = System.currentTimeMillis(); //最后一个非叶子节点 ,满二叉树最后一层节点数=前面所有层总和+1 n/2会向下取整 数组下标从0开始编号 int index = n.length / 2 - 1; //最大堆 for (int i = index; i >= 0; i--) { adjustHead(n, i, n.length - 1); } for (int i = n.length - 1; i > 0; i--) { swap(n, i, 0); adjustHead(n, 0, i - 1); } logger.info("runTime for headSort ={}", System.currentTimeMillis() - start); } public static void adjustHead(int[] n, int index, int end) { //index的左节点(index+1)*2-1=2*index+1 (数组索引从0开始) int left = 2 * index + 1; if (left > end) { return; } int right = left + 1; int maxIndex = left; //=号 if (right <= end && n[right] > n[left]) { maxIndex = right; } if (n[index] < n[maxIndex]) { swap(n, index, maxIndex); adjustHead(n, maxIndex, end); } } /** * @param n 并归 * 数组分割成多断,断内有序,相邻两段合并 * 时间复杂度O(nlogn) */ public static void returnSort(int[] n) { Long start = System.currentTimeMillis(); returnArray(n, 0, n.length - 1); logger.info("runTime for returnSort ={}", System.currentTimeMillis() - start); } public static void returnArray(int[] n, int start, int end) { if (start == end) { return; } //向下取整 int mid = start + (end - start) / 2; returnArray(n, start, mid); //因为向下取整所以mid+1 returnArray(n, mid + 1, end); merge(n, start, mid + 1, end); } public static void merge(int[] n, int start1, int start2, int end2) { int start = start1; int end = end2; int end1 = start2 - 1; //缓存 int[] tem = new int[end2 - start1 + 1]; int i; for (i = 0; i < tem.length - 1 && start1 <= end1 && start2 <= end2; i++) { tem[i] = n[start1] < n[start2] ? n[start1++] : n[start2++]; } while (start1 <= end1) { tem[i++] = n[start1++]; } while (start2 <= end2) { tem[i++] = n[start2++]; } //缓存写入数组位置 i--; while (start <= end) { n[end--] = tem[i--]; } } /** * @param n 插入 * 前面数组看成有序的,i跟前边的序列倒序对比,如果有比i位置大的数则向后移动 * 直到找到i的位置,将数据插入 * O(n^2) */ public static void insertSort(int[] n) { Long start = System.currentTimeMillis(); for (int i = 1; i < n.length; i++) { int tem = n[i]; int j = i; while (j > 0 && n[j - 1] > tem) { n[j] = n[j - 1]; j--; } n[j] = tem; } logger.info("runtime for insertSort ={}", System.currentTimeMillis() - start); } /** * @param n 希尔 * 数组分组,组内插入,扩大分组 */ public static void hillSort(int[] n) { Long start = System.currentTimeMillis(); //gap--组数,每次组数减半,组内元素个数加倍 for (int gap = n.length / 2; gap > 0; gap /= 2) { for (int i = gap; i < n.length; i++) { int tem = n[i]; int j = i; //每个数跟tem比较,比tem小的向后移动 while (j >= gap && n[j - gap] > tem) { n[j] = n[j - gap]; j = j - gap; } n[j] = tem; } } logger.info("runtime for hillSort ={}", System.currentTimeMillis() - start); } /** * @param n 选择 * 每次从剩余的序列中选出最小值放在剩余序列开头 */ public static void choiceSort(int[] n) { Long start = System.currentTimeMillis(); for (int i = 0; i < n.length; i++) { //记录最小值下标 int minIndex = i; for (int j = i + 1; j < n.length; j++) { if (n[j] < n[minIndex]) { //更新最小值下标 minIndex = j; } } //将最小值放到合适位置 swap(n, i, minIndex); } logger.info("runtime for choiceSort ={}", System.currentTimeMillis() - start); } /** * @param n 计数 * 辅助数组k长度为max-min+1,记录每个值出现的次数,eg:k[0]记录min出现的次数 */ public static void countSort(int[] n) { Long start = System.currentTimeMillis(); int max = n[0]; int min = n[0]; for (int i = 1; i < n.length; i++) { max = max > n[i] ? max : n[i]; min = min < n[i] ? min : n[i]; } int[] k = new int[max - min + 1]; for (int i = 0; i < n.length; i++) { k[n[i] - min]++; } int j = 0; int i = 0; while (j < k.length) { while (k[j] > 0) { n[i++] = j + min; k[j]--; } j++; } logger.info("runtime for countSort={}", System.currentTimeMillis() - start); } /** * @param arr 桶 * 计数的优化?为啥时间比计数更长? */ public static void bucketSort(int[] arr) { Long start = System.currentTimeMillis(); int bucketSize = 5; int minValue = arr[0]; int maxValue = arr[0]; for (int value : arr) { if (value < minValue) { minValue = value; } else if (value > maxValue) { maxValue = value; } } int bucketCount = (maxValue - minValue) / bucketSize + 1; int[][] buckets = new int[bucketCount][bucketSize]; // 利用映射函数将数据分配到各个桶中 for (int i = 0; i < arr.length; i++) { int index = (arr[i] - minValue) / bucketSize; int indexBucket = (arr[i] - minValue) % bucketSize; buckets[index][indexBucket]++; } int arrIndex = 0; for (int i = 0; i < bucketCount; i++) { int j = 0; while (j < bucketSize) { while (buckets[i][j] > 0) { arr[arrIndex++] = i * bucketSize + j +minValue; buckets[i][j]--; } j++; } } logger.info("runtime for bucketSort ={}", System.currentTimeMillis() - start); } /** * * 基数 *http://bubkoo.com/2014/01/15/sort-algorithm/radix-sort/ *思想是个位桶排序,然后十位桶排序。。。。。。最后排序完成 *如何解决桶排序扩容浪费时间问题?如果初始化数组长度的桶,浪费空间还不如计数法 */ }

你可能感兴趣的:(java)