基础算法系列(十九)排序算法之内省排序

来源:互联网 发布:苹果录屏用什么软件 编辑:程序博客网 时间: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
原创粉丝点击