堆排序算法Java面向对象实现
来源:互联网 发布:淘宝客营销案例 编辑:程序博客网 时间:2024/06/06 00:28
堆排序算法介绍
堆是一种重要的数据结构,为一棵完全二叉树, 底层如果用数组存储数据的话,假设某个元素为序号为i(Java数组从0开始,i为0到n-1),如果它有左子树,那么左子树的位置是2i+1,如果有右子树,右子树的位置是2i+2,如果有父节点,父节点的位置是(n-1)/2取整。分为最大堆和最小堆,最大堆的任意子树根节点不小于任意子结点,最小堆的根节点不大于任意子结点。所谓堆排序就是利用堆这种数据结构来对数组排序,我们使用的是最大堆。处理的思想和冒泡排序,选择排序非常的类似,一层层封顶,只是最大元素的选取使用了最大堆。最大堆的最大元素一定在第0位置,构建好堆之后,交换0位置元素与顶即可。堆排序为原位排序(空间小), 且最坏运行时间是O(nlgn),是渐进最优的比较排序算法。
实现思路
堆排序简单来说可以概括为三个步骤:
1.根据数据建立无序的堆
2.对堆按大顶堆或小顶堆调整。大顶堆即是满足树中根节点的值始终大于孩子节点的值,局部也满足这个条件,小顶堆相反。
3.每一次调整过后再顶部得到这些数据的最大值或最小值,出堆,并把最后一个节点放到顶部,以此循环,直到堆里的数据全部给出。
具体代码
堆排序类
public class HeapSort<T extends Comparable<T>> { private List<T> sub;// 排序资源列表 private Integer listLength = 0;// 元素个数 private Integer nodeNum = 0;// 堆中节点个数 private Node top;// 顶节点 private Node end;// 最后一个节点 private Node end2;// 倒数第二个节点 private List<T> result = new ArrayList<T>();//排序结果 public HeapSort(List<T> srcList) { this.nodeNum = 1; this.top = new Node((T)srcList.get(0), 1, 1);// 顶节点默认层数为1,编号为1 this.sub = srcList.subList(1, srcList.size()); this.listLength = srcList.size(); this.end = null; createHeap(this.top); } // 创建堆 private void createHeap(Node h) { if (sub == null || sub.size() <= 0) { return; } // 添加左孩子 createLeftChild(h); // 添加右孩子 createRightChild(h); return; } // 创建左孩子 private void createLeftChild(Node h) { if (h.getLeft() != null) { return; } if (listLength >= h.getNum().intValue() * 2) {// 可以有左孩子 nodeNum++; Node leftChild = new Node((T)sub.get(0), h.getFloor() + 1, h.getNum() * 2); h.setLeft(leftChild); leftChild.setParent(h); if (leftChild.getNum() == listLength) {// 最后一个节点 end = leftChild; } sub = sub.subList(1, sub.size()); createHeap(leftChild); }else{ end = h; } return; } // 创建右孩子 private void createRightChild(Node h) { if (h.getRight() != null) { return; } if (listLength >= h.getNum().intValue() * 2 + 1) {// 可以有右孩子 nodeNum++; Node rightChild = new Node((T)sub.get(0), h.getFloor() + 1, h.getNum() * 2 + 1); h.setRight(rightChild); rightChild.setParent(h); if (rightChild.getNum() == listLength) {// 最后一个节点 end = rightChild; } sub = sub.subList(1, sub.size()); createHeap(rightChild); } return; } /** * 调整大顶堆,并且返回最顶端的值 * @param h 根节点 * @return */ private T adjustMaxHeap(Node h) { // 通过迭代遍历根节点和孩子节点,调整为根节点最大 if (h == null) { return null; } if(nodeNum==1){ return (T) top.getValue(); } if (h.getNum().equals(nodeNum - 1)) {// 调整堆的时候添加上倒数第二个节点的引用,以便删除最后一个节点后将end指向此节点 end2 = h; } T top = (T) h.getValue(); // 调整左孩子 T maxLeft = adjustMaxHeap(h.getLeft()); // 调整右孩子 T maxRight = adjustMaxHeap(h.getRight()); if (maxLeft == null && maxRight == null) {// 没有左右孩子 return (T) h.getValue(); } else if (maxLeft == null && maxRight != null) {// 没有左孩子 if (maxRight.compareTo(top)>0) { h.setValue(maxRight); h.getRight().setValue(top); } } else if (maxLeft != null && maxRight == null) {// 没有右孩子 if (maxLeft.compareTo(top)>0) { h.setValue(maxLeft); h.getLeft().setValue(top); } } else {// 有左右孩子 if (maxLeft.compareTo(top)>0 || maxRight.compareTo(top)>0) { if (maxLeft.compareTo(maxRight)>=0) {// 左孩子最大 h.setValue(maxLeft); h.getLeft().setValue(top); } else {// 右孩子最大 h.setValue(maxRight); h.getRight().setValue(top); } } } return (T) h.getValue(); } /** * 堆排序方法(大顶堆) * @param srcList * @return */ public List<T> sort() { // 循环调整堆 while (floorMoreOne()) { T max = adjustMaxHeap(top); //stack.push(max); result.add((T) max); top.setValue(end.getValue()); Node parent = end.getParent(); if (end.getParent() == null) { break; } if (parent.getLeft() != null && parent.getLeft().getNum().intValue() == end.getNum().intValue()) { parent.setLeft(null); } if (parent.getRight() != null && parent.getRight().getNum().intValue() == end.getNum().intValue()) { parent.setRight(null); } nodeNum--; end = end2; // end指向倒数第二个节点 } result.add((T) top.getValue()); return result; } // 判断堆的层数是否大于一 private boolean floorMoreOne() { if (top.getLeft() != null || top.getRight() != null) { return true; } return false; }}
节点类
public class Node<T> { private T value;// 节点的值 private Integer floor;// 节点所在层 private Integer num;// 节点编号 private Node parent;// 父节点 private Node left;// 左孩子 private Node right;// 右孩子 public Node() { } public Node(T value) { super(); this.value = value; } public Node(T value, Integer floor) { super(); this.value = value; this.floor = floor; } public Node(T value, Integer floor, Integer num) { super(); this.value = value; this.floor = floor; this.num = num; } public Node<T> getLeft() { return left; } public Integer getNum() { return num; } public void setLeft(Node leftChild) { this.left = leftChild; } public void setRight(Node rightChild) { this.right = rightChild; } public void setParent(Node h) { this.parent = h; } public int getFloor() { return floor; } public T getValue() { return value; } public Node getRight() { return right; } public void setValue(T value) { this.value = value; } public Node getParent() { return parent; }}
这个实现中用到了泛型,可以对多种类型排序,只需要实现comparable接口并实现了compareTo方法。
测试代码
public void test01(){ @SuppressWarnings("unchecked") int j=0; String[] strs = new String[1000]; while(j<strs.length){ int len = (int) Math.floor(Math.random()*10+1); byte[] bytes = new byte[len]; for(int k=0;k<len;k++){ bytes[k] = (byte) Math.floor(Math.random()*26+65); } strs[j] = new String(bytes); j++; } HeapSort<String> sort = new HeapSort<String>((List<String>)Arrays.asList(strs)); List<String> list1 = sort.sort(); for(String o:list1){ if(list1.indexOf(o)%10==0){ System.out.println(o.toString()+" "); }else{ System.out.print(o.toString()+" "); } } }
测试结果
这个实例是纯java面向对象的实现,相比较原生面向过程的实现处理速度回慢,占用资源也多,进攻学习用。如果有什么问题,希望道友们慷慨指正。
阅读全文
0 0
- 堆排序算法Java面向对象实现
- 堆排序算法-java实现
- Java实现堆排序算法
- Java实现堆排序算法
- 堆排序算法java实现
- 堆排序算法--Java实现
- 堆排序算法java实现
- Java实现排序算法之堆排序
- java实现排序算法之堆排序
- Java实现排序算法2:堆排序
- java实现简单排序算法:堆排序
- 排序算法之堆排序java实现
- 排序算法之堆排序 Java 实现
- 堆排序算法(java实现)
- 堆排序算法的java实现
- 堆排序算法原理及JAVA实现
- 堆排序算法(C & Java 实现)
- 算法导论堆排序Java实现
- 投资养老社保不如买房?房产税还未出台就已处境尴尬
- Java集合框架05 fail-fast机制
- host头攻击解决方法
- byte数组与文件的转换
- Git语句
- 堆排序算法Java面向对象实现
- unity中全息投影带贴图shader
- java常用类--日期和时间
- 【机器学习】归一化
- Java入门学习(一)
- 安卓打包遇到的问题
- java基础之运算符
- LintCode245子树
- Unity Shader 学习笔记(15) 立方体纹理、反射、折射、菲涅尔反射