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 快排
	 *          <p>
	 *          左右两个指针,取排序开始位为基准值,右指针遍历比基准值小的位置跟左指针交换数据,
	 *          左指针遍历比基准值大的值跟右指针交换位置,最后左右指针重合将基准值放到重合位置
	 *          时间复杂度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/
	 *思想是个位桶排序,然后十位桶排序。。。。。。最后排序完成
	 *如何解决桶排序扩容浪费时间问题?如果初始化数组长度的桶,浪费空间还不如计数法
	 */




}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值