网站首页 > java教程 正文
堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的二叉堆。
堆的定义
n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系之一时,称之为堆。
情形1:ki <= k2i 且ki <= k2i+1 (最小化堆或小顶堆)
情形2:ki >= k2i 且ki >= k2i+1 (最大化堆或大顶堆)
其中i=1,2,…,n/2向下取整;
若将和此序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左、右孩子结点的值。
由此,若序列{k1,k2,…,kn}是堆,则堆顶元素(或完全二叉树的根)必为序列中n个元素的最小值(或最大值)。
堆的存储
一般用数组来表示堆,若根结点存在序号0处, i结点的父结点下标就为(i-1)/2。i结点的左右子结点下标分别为2*i+1和2*i+2。
堆排序的实现
实现堆排序需要解决两个问题:
1.如何由一个无序序列建成一个堆?
2.如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
先考虑第二个问题,一般在输出堆顶元素之后,视为将这个元素排除,然后用表中最后一个元素填补它的位置,自上向下进行调整:首先将堆顶元素和它的左右子树的根结点进行比较,把最小的元素交换到堆顶;然后顺着被破坏的路径一路调整下去,直至叶子结点,就得到新的堆。
我们称这个自堆顶至叶子的调整过程为“筛选”。
从无序序列建立堆的过程就是一个反复“筛选”的过程。
public class HeapSort { int[] arr; public static void main(String[] args) { HeapSort heapSor = new HeapSort(); int[] arr = new int[100]; //0下标放的是数组长度, for(int i=arr.length-1;i>=0;i--){ Random r = new Random(); arr[i] = i*r.nextInt(10000); } Date date1 = new Date(); System.out.println("----------开始----------"+date1); heapSor.arr = arr; heapSor.heapSort(arr); Date date2 = new Date(); System.out.println("----------结束----------"+date2); for(int i=0;i<arr.length;i++){ System.out.println(arr[i]); } System.out.println("用时:"+(date2.getTime()-date1.getTime())); } void heapAdjust(int[] arr,int s,int m){ //已知arr[s...m]中记录的关键字除arr[s]之外均满足堆的定义,本函数调整arr[s]的关键字,使arr[s...m]成为一个最大堆 int rc = arr[s]; //s是最后一个非叶子节点 for(int j=2*s;j <= m;j = s*2){ if(j<m && arr[j]<arr[j+1]) j++; //j为key较大的下标 if(rc >= arr[j]) break; arr[s] = arr[j]; //上移到父节点 s=j; } arr[s]=rc; //要放入的位置 } void heapSort(int[] arr){ //对数组进行建堆操作,就是从最后一个非叶结点进行筛选的过程 for(int i=(arr.length-1)/2;i > 0;i--){//因为0没有使用,所以length-1 heapAdjust(arr,i,arr.length-1); } System.out.println("........建堆完成............."); outputArr(1); for(int i=arr.length-1; i>1; i--){ int temp = arr[1]; arr[1] = arr[i]; arr[i] = temp; heapAdjust(arr,1,i-1); } } void outputArr(int i){ if(i <= arr[0]){ System.out.println(arr[i]); outputArr(i*2); //左 outputArr(i*2+1); //右 } } }
猜你喜欢
- 2024-10-09 一遍记住 8 种排序算法与 Java 代码实现
- 2024-10-09 java程序员必知的八大排序(java编程排序算法实现)
- 2024-10-09 插入排序算法,就这么简单,还学不会算我输
- 2024-10-09 程序员必知的十大基础实用算法之-快速排序算法
- 2024-10-09 【数据结构与算法】十大经典排序算法-快速排序
- 2024-10-09 经常用到的的排序(快速排序和归并排序)简单的计算机算法学习
- 2024-10-09 排序算法——快排(快速排序算法实例讲解)
- 2024-10-09 七种基于比较的排序,基于Java实现,收藏一下?
- 2024-10-09 十大经典排序算法动画与解析,看我就够了!(配代码完全版)
- 2024-10-09 看动图学算法(六):快速排序的原理和Java讲解
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)