排序算法(二)--堆排序(JAVA)
2018-01-12 11:30
323 查看
堆的一个很重要的应用就是堆排序,和快速排序一样,堆排序的时间复杂度也是O(NlgN)
堆排序的实现思路一:
1.创建小根堆
2.每次删除顶部元素并将顶部元素输出(删除的函数中有调整的过程,每次调整)
时间复杂度:O(N·logN)
Input:
14
99 5 36 2 19 1 46 12 7 22 25 28 17 92
Output:
1 2 5 7 12 17 19 22 25 28 36 46 92 99
堆排序的实现思路二:
1.创建大根堆
2.h[1]与h
交换
3.对h[1]向下调整, n–
时间复杂度:O(N·logN)
Input:
14
99 5 36 2 19 1 46 12 7 22 25 28 17 92
Output:
1 2 5 7 12 17 19 22 25 28 36 46 92 99
堆是一种优先队列的数据结构
对于普通队列来说,在进行插入操作时比较方便,但是如果寻找队列中最大(或最小)的元素则时间复杂度较高;
对于已排序的数组来说,查找最大(或最小)元素并不在话下,但是插入元素则需要后面的元素整体后移,时间复杂度依旧很高。
而优先队列这种结构,则可以很好的解决上面的两种操作。
之前的Dijkstra算法就可以通过堆来进行优化。
堆排序的实现思路一:
1.创建小根堆
2.每次删除顶部元素并将顶部元素输出(删除的函数中有调整的过程,每次调整)
时间复杂度:O(N·logN)
Input:
14
99 5 36 2 19 1 46 12 7 22 25 28 17 92
Output:
1 2 5 7 12 17 19 22 25 28 36 46 92 99
import java.util.Scanner; public class heap { static int n, num = 0; static int[] h = new int[15]; static Scanner input = new Scanner(System.in); public static void main(String[] args) { n = input.nextInt(); for (int i = 1; i <= n; i++) { h[i] = input.nextInt(); } num = n; create(); for (int i = 1; i <= n; i++) { System.out.print(deletemax() + " "); } } private static void create() { /** * 从最后一个非叶结点到第1个结点向上调整 * */ for (int i = num / 2; i >= 1; i--) { siftdown(i); } } private static int deletemax() { int temp = h[1]; h[1] = h[num]; num--; siftdown(1); return temp; } private static void siftup(int i) { int flag = 0; /** * 堆顶 * */ if (i == 1) { return; } while (i != 1 && flag == 0) { /** * 当前节点是否小于父结点 * */ if (h[i] < h[i/2]) { int temp = h[i]; h[i] = h[i/2]; h[i/2] = temp; } else { flag = 1; } /** * 向上调整 * */ i = i/2; } } private static void siftdown(int i) { int t, flag = 0; while (i * 2 <= num && flag == 0) { if (h[i] > h[i*2]) { t = i * 2; } else { t = i; } if (i * 2 + 1 <= num) { if (h[t] > h[i * 2 + 1]) { t = i * 2 + 1; } } if (t != i) { int temp = h[t]; h[t] = h[i]; h[i] = temp; i = t; } else { flag = 1; } } } }
堆排序的实现思路二:
1.创建大根堆
2.h[1]与h
交换
3.对h[1]向下调整, n–
时间复杂度:O(N·logN)
Input:
14
99 5 36 2 19 1 46 12 7 22 25 28 17 92
Output:
1 2 5 7 12 17 19 22 25 28 36 46 92 99
import java.util.Scanner; public class heapPlus { static int num, n = 0; static int[] h = new int[15]; static Scanner input = new Scanner(System.in); public static void main(String[] args) { n = input.nextInt(); for (int i = 1; i <= n; i++) { h[i] = input.nextInt(); } num = n; create(); heapsort(); for (int i = 1; i <= n; i++) { System.out.print(h[i] + " "); } } private static void heapsort() { while (num > 1) { int temp = h[num]; h[num] = h[1]; h[1] = temp; num--; siftdown(1); } } private static void create() { /** * 从最后一个非叶结点到第1个结点向上调整 * */ for (int i = num / 2; i >= 1; i--) { siftdown(i); } } private static void siftup(int i) { int flag = 0; /** * 堆顶 * */ if (i == 1) { return; } while (i != 1 && flag == 0) { /** * 当前节点是否小于父结点 * */ if (h[i] > h[i/2]) { int temp = h[i]; h[i] = h[i/2]; h[i/2] = temp; } else { flag = 1; } /** * 向上调整 * */ i = i/2; } } private static void siftdown(int i) { int t, flag = 0; while (i * 2 <= num && flag == 0) { if (h[i] < h[i*2]) { t = i * 2; } else { t = i; } if< b94f /span> (i * 2 + 1 <= num) { if (h[t] < h[i * 2 + 1]) { t = i * 2 + 1; } } if (t != i) { int temp = h[t]; h[t] = h[i]; h[i] = temp; i = t; } else { flag = 1; } } } }
堆是一种优先队列的数据结构
对于普通队列来说,在进行插入操作时比较方便,但是如果寻找队列中最大(或最小)的元素则时间复杂度较高;
对于已排序的数组来说,查找最大(或最小)元素并不在话下,但是插入元素则需要后面的元素整体后移,时间复杂度依旧很高。
而优先队列这种结构,则可以很好的解决上面的两种操作。
之前的Dijkstra算法就可以通过堆来进行优化。
相关文章推荐
- 【转】排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- Java排序算法(三):堆排序
- 排序算法复习(Java实现)(二): 归并排序,堆排序,桶式排序,基数排序
- 一步一步解析java排序算法---堆排序(最大堆)
- java排序算法之堆排序
- 七大排序算法(冒泡,选择,插入,二分法排序,希尔,快速,合并,堆排序)的java实现
- 排序算法之堆排序(Java)
- Java实现排序算法——堆排序
- 排序算法之堆排序(JAVA实现)
- Java排序算法:堆排序
- 【排序算法】堆排序原理及Java实现
- 【Java】八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序 、快速排序、归并排序、堆排序和LST基数排序
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序
- 八种排序算法Java实现-堆排序
- 排序算法之插入排序(Java)及堆排序
- 排序算法复习(Java实现):插入,冒泡,选择,Shell,快速排序, 归并排序,堆排序,桶式排序,基数排序
- Java排序算法总结(六):堆排序
- Java排序算法(三):堆排序
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- [置顶] 排序算法之堆排序 Java 实现