标签:and war src 原理 build heapsort 堆排 不同 标准
最近在看《算法笔记》,如果单从算法来说,这本书真正做到了短小精悍,首先以排序入题,那么我们今天也来说说排序。
排序算法很多,我们按是否可以实现排序分为比较排序和非比较排序,在比较排序中常见的有,比较排序,梳排序,堆排序,归并排序,快递排序,内省排序等,非比较排序如,通排序,基数排序等。如果按传统的分类,则可以分为插入排序、折半插入排序、Shell排序、归并排序、直接选择排序、堆排序、冒泡排序、快速排序、桶式排序、基数排序等,各大排序基于不同的场景设置,各有优势。接下来就选取几个常见的说明。
BOOL CombSort(datatype *array, int size) { int i, j; int increment; if(array == NULL ) { return FALSE; } increment = size; while(TRUE) { increment = (int)(increment / LAPSE_RATE); for(i = 0; i < increment; i++) { for(j = i+increment; j < size; j += increment) { if(array[j] < array[j-increment]) { Swap(array+j, array+j-increment); } } } if(increment <= 1) { break; } } return TRUE; }
public class ArrayUtils { public static void printArray(int[] array) { System.out.print("{"); for (int i = 0; i < array.length; i++) { System.out.print(array[i]); if (i < array.length - 1) { System.out.print(", "); } } System.out.println("}"); } public static void exchangeElements(int[] array, int index1, int index2) { int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } }
public class HeapSort { public static void main(String[] args) { int[] array = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 }; System.out.println("Before heap:"); ArrayUtils.printArray(array); heapSort(array); System.out.println("After heap sort:"); ArrayUtils.printArray(array); } public static void heapSort(int[] array) { if (array == null || array.length <= 1) { return; } buildMaxHeap(array); for (int i = array.length - 1; i >= 1; i--) { ArrayUtils.exchangeElements(array, 0, i); maxHeap(array, i, 0); } } private static void buildMaxHeap(int[] array) { if (array == null || array.length <= 1) { return; } int half = array.length / 2; for (int i = half; i >= 0; i--) { maxHeap(array, array.length, i); } } private static void maxHeap(int[] array, int heapSize, int index) { int left = index * 2 + 1; int right = index * 2 + 2; int largest = index; if (left < heapSize && array[left] > array[index]) { largest = left; } if (right < heapSize && array[right] > array[largest]) { largest = right; } if (index != largest) { ArrayUtils.exchangeElements(array, index, largest); maxHeap(array, heapSize, largest); } } }
public class MergeSortTest { public static void main(String[] args) { int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 }; print(data); mergeSort(data); System.out.println("排序后的数组:"); print(data); } public static void mergeSort(int[] data) { sort(data, 0, data.length - 1); } public static void sort(int[] data, int left, int right) { if (left >= right) return; // 找出中间索引 int center = (left + right) / 2; // 对左边数组进行递归 sort(data, left, center); // 对右边数组进行递归 sort(data, center + 1, right); // 合并 merge(data, left, center, right); print(data); } /** * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 * * @param data * 数组对象 * @param left * 左数组的第一个元素的索引 * @param center * 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引 * @param right * 右数组最后一个元素的索引 */ public static void merge(int[] data, int left, int center, int right) { // 临时数组 int[] tmpArr = new int[data.length]; // 右数组第一个元素索引 int mid = center + 1; // third 记录临时数组的索引 int third = left; // 缓存左数组第一个元素的索引 int tmp = left; while (left <= center && mid <= right) { // 从两个数组中取出最小的放入临时数组 if (data[left] <= data[mid]) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个) while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 将临时数组中的内容拷贝回原数组中 // (原left-right范围的内容被复制回原数组) while (tmp <= right) { data[tmp] = tmpArr[tmp++]; } } public static void print(int[] data) { for (int i = 0; i < data.length; i++) { System.out.print(data[i] + "\t"); } System.out.println(); } }
public class ArrayUtils { public static void printArray(int[] array) { System.out.print("{"); for (int i = 0; i < array.length; i++) { System.out.print(array[i]); if (i < array.length - 1) { System.out.print(", "); } } System.out.println("}"); } public static void exchangeElements(int[] array, int index1, int index2) { int temp = array[index1]; array[index1] = array[index2]; array[index2] = temp; } }测试
public class QuickSort { public static void main(String[] args) { int[] array = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3 }; System.out.println("Before sort:"); ArrayUtils.printArray(array); quickSort(array); System.out.println("After sort:"); ArrayUtils.printArray(array); } public static void quickSort(int[] array) { subQuickSort(array, 0, array.length - 1); } private static void subQuickSort(int[] array, int start, int end) { if (array == null || (end - start + 1) < 2) { return; } int part = partition(array, start, end); if (part == start) { subQuickSort(array, part + 1, end); } else if (part == end) { subQuickSort(array, start, part - 1); } else { subQuickSort(array, start, part - 1); subQuickSort(array, part + 1, end); } } private static int partition(int[] array, int start, int end) { int value = array[end]; int index = start - 1; for (int i = start; i < end; i++) { if (array[i] < value) { index++; if (index != i) { ArrayUtils.exchangeElements(array, index, i); } } } if ((index + 1) != end) { ArrayUtils.exchangeElements(array, index + 1, end); } return index + 1; } }
public class InsertSortTest { public static void insertSort(int[] array) { if (array == null || array.length < 2) { return; } for (int i = 1; i < array.length; i++) { int currentValue = array[i]; int position = i; for (int j = i - 1; j >= 0; j--) { if (array[j] > currentValue) { array[j + 1] = array[j]; position -= 1; } else { break; } } array[position] = currentValue; } } public static void main(String[] args) { int[] array = { 3, -1, 0, -8, 2, 1 }; ArrayUtils.printArray(array); insertSort(array); ArrayUtils.printArray(array); } }
/** * 内省排序升序 */ 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; } }
public class BucketSort { /** * 桶排序算法,对arr进行桶排序,排序结果仍放在arr中 * @param arr */ static void bucketSort(double arr[]){ int n = arr.length; ArrayList arrList[] = new ArrayList [n]; //把arr中的数均匀的的分布到[0,1)上,每个桶是一个list,存放落在此桶上的元素 for(int i =0;i<n;i++){ int temp = (int) Math.floor(n*arr[i]); if(null==arrList[temp]) arrList[temp] = new ArrayList(); arrList[temp].add(arr[i]); } //对每个桶中的数进行插入排序 for(int i = 0;i<n;i++){ if(null!=arrList[i]) insert(arrList[i]); } //把各个桶的排序结果合并 int count = 0; for(int i = 0;i<n;i++){ if(null!=arrList[i]){ Iterator iter = arrList[i].iterator(); while(iter.hasNext()){ Double d = (Double)iter.next(); arr[count] = d; count++; } } } } /** * 用插入排序对每个桶进行排序 * @param list */ static void insert(ArrayList list){ if(list.size()>1){ for(int i =1;i<list.size();i++){ if((Double)list.get(i)<(Double)list.get(i-1)){ double temp = (Double) list.get(i); int j = i-1; for(;j>=0&&((Double)list.get(j)>(Double)list.get(j+1));j--) list.set(j+1, list.get(j)); list.set(j+1, temp); } } } } /** * 测试..... * 这里的测试数据是一个含n个元素的数组,且每个元素满足0<=arr[i]<1 */ public static void main(String[] args) { double arr[] = {0.78,0.17,0.39,0.26,0.72,0.94,0.21,0.12,0.23,0.68}; bucketSort(arr); for(int i = 0;i<arr.length;i++) System.out.println(arr[i]); } }
标签:and war src 原理 build heapsort 堆排 不同 标准
原文地址:http://blog.csdn.net/xiangzhihong8/article/details/53175932