排序II
来源:互联网 发布:sql like 编辑:程序博客网 时间:2024/05/22 06:13
归并排序
归并排序的思想:假设初始序列含有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]向上取整个长度为2或者1的有序子序列,再两两归并。这种办法称为2路归并排序。
package com.weixuan.sort.merge;public class MergeSort { public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) System.out.print(array[i] + "\t"); } public static void mergeSort(int[] data) { mergeSortCore(data, 0, data.length - 1); } private static void mergeSortCore(int[] data, int low, int high) { int midIndex = (low + high) >> 1; if (low < high) { // 左边 mergeSortCore(data, low, midIndex); // 右边 mergeSortCore(data, midIndex + 1, high); // 左右归并 merge(data, low, midIndex, high); } } private static void merge(int[] data, int low, int mid, int high) { int[] temp = new int[high - low + 1]; int i = low;// 左指针 int j = mid + 1;// 右指针 int k = 0; // 把较小的数先移到新数组中 while (i <= mid && j <= high) { if (data[i] < data[j]) { temp[k++] = data[i++]; } else { temp[k++] = data[j++]; } } // 把左边剩余的数移入数组 while (i <= mid) { temp[k++] = data[i++]; } // 把右边边剩余的数移入数组 while (j <= high) { temp[k++] = data[j++]; } // 把新数组中的数覆盖nums数组 for (int k2 = 0; k2 < temp.length; k2++) { data[k2 + low] = temp[k2]; } }}
性能
空间复杂度
时间复杂度
比较过程是两两比较,不存在跳跃,是稳定的排序。
过程 初始序列{50,10,90,30,70,40,80,60,20}
堆排序
package com.weixuan.sort.heap;public class HeapSort { public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) System.out.print(array[i] + "\t"); } /** * @param data * 原始数组序列 * @brief 构建堆 */ private static void buildHeap(int[] data) { /** * 获取最后一个非叶子节点 */ int begin = data.length / 2; for (int i = begin; i >= 0; i--) { adjustHeap(data, data.length, i); } } /** * @param data * 要调整的数组 * @param heapSize * 长度 * @param index * 需要调整的节点的下标 * @brief 调整堆 */ private static void adjustHeap(int[] data, int heapSize, int index) { /** * 节点index的左孩子下标 */ int leftChildSubscript = 2 * index + 1; /** * 节点index的右孩子下标 */ int rightChildSubscript = 2 * index + 2; /** * 最大元素的初始下标 */ int largestSubscript = index; /** * 找到最大元素 */ /** * 如果当前根节点小于左孩子的值,那么最大元素的下标为左孩子的下标. */ if ((leftChildSubscript < heapSize) && (data[largestSubscript] < data[leftChildSubscript])) { largestSubscript = leftChildSubscript; } /** * 如果当前根节点小于右孩子的值,那么最大元素的下标为右孩子的下标. */ if ((rightChildSubscript < heapSize) && (data[largestSubscript] < data[rightChildSubscript])) { largestSubscript = rightChildSubscript; } /** * 将最大元素调整至根节点. 根节点不是最大的,那么就调整. */ if (index != largestSubscript) { /** * 将根节点的值与子节点中的最大值进行调整. */ swapElements(data, index, largestSubscript); /** */ adjustHeap(data, heapSize, largestSubscript); } } private static void swapElements(int[] data, int index1, int index2) { int temp = data[index1]; data[index1] = data[index2]; data[index2] = temp; } /** * @param data * 原始数组 * @brief 堆排序 */ public static void heapSort(int[] data) { int length = data.length; /** * 构建堆 */ buildHeap(data); while (length >= 1) { /** * 将堆的最后一个元素与堆顶元素交换. */ swapElements(data, 0, length - 1); length--; /** * 将剩余元素调整为堆 */ adjustHeap(data, length, 0); } }}
性能
堆排序的运行时间主要耗费在初始创建堆和重新构建堆上。
构建堆的时间复杂度是
时间复杂度是
插入排序
在待排序的元素序列基本有序的前提下,效率最高的排序方法是插入排序
思想:将一个记录插入到已经排序的有序表中,从而得到一个新的记录+1的有序表。
package com.weixuan.sort.insert;public class InsertSort { public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) System.out.print(array[i] + "\t"); } public static void insertSort(int[] data) { for (int i = 1; i < data.length; i++) { if (data[i] < data[i - 1]) { int temp = data[i]; // 需要插入的数字 int j = i - 1; // 数组后移 while (j >= 0 && data[j] > temp) { data[j + 1] = data[j]; j--; } data[j + 1] = temp; } } }}
性能分析
当数组基本有序时,性能最好,比较n-1次,没有数据移动。时间复杂度为
最差情况,待排数据是逆序的,需要比较
次,移动的次数是
此时的时间复杂度是
平均情况下,平均的比较次数和移动次数是
shell排序
本质是分组插入排序
package com.weixuan.sort.shell;public class ShellSort { public static void printArray(int[] array) { for (int i = 0; i < array.length; i++) System.out.print(array[i] + "\t"); } public static void shellSort(int[] data) { int increment = data.length; int j; do { increment = increment / 3 + 1; for (int i = increment; i < data.length; i++) { if (data[i] < data[i - increment]) { int temp = data[i]; for (j = i - increment; j >= 0 && temp < data[j]; j -= increment) { data[j + increment] = data[j]; } data[j + increment] = temp; } } } while (increment > 1); }}
性能
性能和步长(increment)有关,最佳时间复杂度是
比较是跳跃性的,是非稳定的排序算法
外部排序
外部排序还要考虑IO效率
tips
堆排序,冒泡排序 ,快速排序每趟结束时,都有一个元素被放置再在其最终位置上。
0 0
- 排序II
- 合并排序数组 II
- 【LintCode】整数排序II
- LintCode:摆动排序 II
- LintCode:摆动排序 II
- 合并排序数组 II
- 整数排序II-lintcode
- 数据结构—排序II
- lintcode_整数排序 II
- LintCode-整数排序 II
- 整数排序 II
- 整数排序 II
- 整数排序 II
- 整数排序 II
- 整数排序 II
- 464.整数排序 II
- 整数排序 II
- 整数排序 II
- 《剑指offer》斐波那契数列
- 使用注册表表去掉win7桌面图标箭头的方法
- java中关于重载和重写
- HUST 1342Cheat Secretly 有源汇上下界网络流 最小流
- httpd: Could not reliably determine the server's fully qualified domain name
- 排序II
- 如何搭建一个Linux驱动编写环境(centos)
- manacher算法求最长回文串
- poj 2049 Finding Nemo 建图技巧型最短路
- Genymotion配置及使用教程(最新最完整版附各部分下载地址)
- 自定义弹窗
- STL中traits原理
- 二分图
- UVA 753(最大流匹配)