基础算法系列(十九)排序算法之内省排序
来源:互联网 发布:苹果录屏用什么软件 编辑:程序博客网 时间:2024/04/30 06:39
内省排序:又称Introsort,是一个相当偏门的排序算法,是由David Musser在1997年设计出来的。属于
比较排序算法的一种。内省排序的实现过程是这样的,首先由快速排序开始,当递归深度超过一定程度时,
转换为堆排序。所以内省排序既能在常规数据集上实现快速排序的高性能,又能在最坏情况下仍保持
O(N log N) 的时间复杂度。
// 先进行快速排序,当递归深度到达一定深度时,进行堆排序
// 改动快速排序代码,增加返回值为递归次数,当次数大于一定值时停止递归,开始调用堆排序进行排序
/** * 内省排序升序 */public static int sort_neixing_asc(int[] array, int start, int end,int level) {// 先进行快速排序,当递归深度到达一定深度时,进行堆排序// 改动快速排序代码,增加返回值为递归次数,当次数大于一定值时停止递归,开始调用堆排序进行排序level++;int length = end - start + 1;if (length < 2)return level;else if (length == 2) {if (array[start] > array[end]) {int temp = array[end];array[end] = array[start];array[start] = temp;}return level;} else {// 得出最大值和最小值int min = array[start], max = array[start];for (int i = start; i < start + length; i++) {if (array[i] < min)min = array[i];if (array[i] > max)max = array[i];}// 找出合适的中间数(按中间值找,最好是像计数排序一样先统计比元素小的个数,然后按照个数确定哪个做中间数)int absMid = (min + max) / 2;int offset = Math.abs(array[start] - absMid);int relativeMid = array[start];int midIndex = start;for (int i = start; i < start + length; i++)if (Math.abs(array[i] - absMid) < offset) {offset = Math.abs(array[i] - absMid);relativeMid = array[i];}int[] newArray = new int[length];for (int i = 0; i < newArray.length; i++)newArray[i] = -1;for (int i = start, startIndex = 0, endIndex = length - 1; i < start+ length; i++) {if (array[i] < relativeMid) {newArray[startIndex] = array[i];startIndex++;} else if (array[i] > relativeMid) {newArray[endIndex] = array[i];endIndex--;}}for (int i = 0; i < newArray.length; i++)if (newArray[i] == -1)newArray[i] = relativeMid;for (int i = start, newIndex = 0; i < start + length; i++, newIndex++) {array[i] = newArray[newIndex];if (array[i] == relativeMid)midIndex = i;}if (level < 10) {// 递归深度小于10时使用快速排序sort_neixing_asc(array, start, midIndex - 1, level);sort_neixing_asc(array, midIndex + 1, length - 1 + start, level);} else {// 递归深度大于10时使用堆排序sort_dui_asc(array);}return level;}}
/** * 内省排序降序 */public static int sort_neixing_dasc(int[] array, int start, int end,int level) {// 先进行快速排序,当递归深度到达一定深度时,进行堆排序// 改动快速排序代码,增加返回值为递归次数,当次数大于一定值时停止递归,开始调用堆排序进行排序level++;int length = end - start + 1;if (length < 2)return level;else if (length == 2) {if (array[start] < array[end]) {int temp = array[end];array[end] = array[start];array[start] = temp;}return level;} else {// 得出最大值和最小值int min = array[start], max = array[start];for (int i = start; i < start + length; i++) {if (array[i] < min)min = array[i];if (array[i] > max)max = array[i];}// 找出合适的中间数(按中间值找,最好是像计数排序一样先统计比元素小的个数,然后按照个数确定哪个做中间数)int absMid = (min + max) / 2;int offset = Math.abs(array[start] - absMid);int relativeMid = array[start];int midIndex = start;for (int i = start; i < start + length; i++)if (Math.abs(array[i] - absMid) < offset) {offset = Math.abs(array[i] - absMid);relativeMid = array[i];}int[] newArray = new int[length];for (int i = 0; i < newArray.length; i++)newArray[i] = -1;for (int i = start, startIndex = 0, endIndex = length - 1; i < start+ length; i++) {if (array[i] > relativeMid) {newArray[startIndex] = array[i];startIndex++;} else if (array[i] < relativeMid) {newArray[endIndex] = array[i];endIndex--;}}for (int i = 0; i < newArray.length; i++)if (newArray[i] == -1)newArray[i] = relativeMid;for (int i = start, newIndex = 0; i < start + length; i++, newIndex++) {array[i] = newArray[newIndex];if (array[i] == relativeMid)midIndex = i;}if (level < 10) {// 递归深度小于10时使用快速排序sort_neixing_dasc(array, start, midIndex - 1, level);sort_neixing_dasc(array, midIndex + 1, length - 1 + start,level);} else {// 递归深度大于10时使用堆排序sort_dui_dasc(array);}return level;}}
调用
int[] array;array = SortUtil.createRandomArray(200, 1000);//升序SortUtil.sort_neixing_asc(array, 0, array.length - 1, 0);//降序SortUtil.sort_neixing_dasc(array, 0, array.length - 1, 0);
/** * 产生随机数组 */public static int[] createRandomArray(int n, int max) {int[] array = new int[n];boolean[] bool = new boolean[max];for (int i = 0; i < array.length; i++) {int num;do {num = new Random().nextInt(max);} while (bool[num]);bool[num] = true;array[i] = num;}return array;}
0 0
- 基础算法系列(十九)排序算法之内省排序
- 基础算法系列(五)排序算法之冒泡排序
- 基础算法系列(六)排序算法之鸡尾酒排序
- 基础算法系列(七)排序算法之插入排序
- 基础算法系列(八)排序算法之桶排序
- 基础算法系列(九)排序算法之计数排序
- 基础算法系列(十)排序算法之合并排序
- 基础算法系列(十三)排序算法之地精排序
- 基础算法系列(十四)排序算法之图书馆排序
- 基础算法系列(十五)排序算法之选择排序
- 基础算法系列(十六)排序算法之希尔排序
- 基础算法系列(十七)排序算法之堆排序
- 基础算法系列(十八)排序算法之快速排序
- 基础算法系列(十二)排序算法之基数排序
- 十九、字符串排序算法
- 基础算法系列(十一)排序算法之鸽巢排序
- 基础算法系列(二十)排序算法之耐心排序
- 排序算法系列之基本排序算法
- HDU1087(最长上升子序列DP)
- ANDROID内存优化(大汇总——全)
- 使用PageHeap.EXE或GFlags.EXE检查内存越界错误(转)
- onSaveInstanceState执行时机
- java中異常(一)
- 基础算法系列(十九)排序算法之内省排序
- APUE第三章3.2习题分析
- win 7和Ubuntu 14.04双系统安装与卸载
- 安装使用protobuf,及使用C++编写多线程通信
- StageFright框架(三)選擇Video Decoder
- RSA MD5 加密
- QR Code reader
- HR学习笔记2
- response.setContentType()的作用参数详解