zoukankan      html  css  js  c++  java
  • 堆排序

    如果堆的大小是提前知道的,那么可以将堆存储在一个ArrayList或一个数组里。如下图使用数组存储堆,对于位置i处的结点,它的左孩子在位置2i+1处,它的右孩子在位置2i+2处,而它的父亲在位置(i - 1)/2处。

    如下是一些堆具有的常见操作:

    添加一个新结点:

    为了给堆添加一个新结点,首先将它添加到堆的末尾,然后和它的父节点比较,如果大,就上移,直到不必父节点大。

    删除根节点:

    经常需要从堆中删除最大的元素,也就是这个堆中的根节点。删除根节点之后就必须重建这个树以保持堆的特性,重建过程如下:

      将最后一个节点放到根节点当做当前节点;

      然后和左右子节点比较,如果当前节点是这三个节点中最大的,那么这棵树建立成功;如果不是,需要和两个子节点中最大的节点交换位置,然后以当前位置作为当前节点,继续和子节点比较,直到当前节点是最大的,或者当前节点已经成为叶子节点。

    Heap.java代码如下:

    package test;

    public class Heap<E extends Comparable> {

        private java.util.ArrayList<E> list = new java.util.ArrayList<E>();

        public Heap(){}

        public Heap(E[] objects){
            for(int i = 0; i < objects.length; i++)
            add(objects[i]);
        }

        public void add(E newObject){
            list.add(newObject);
            int currentIndex = list.size() - 1;

            while(currentIndex > 0){
                int parentIndex = (currentIndex - 1)/2;
                if(list.get(currentIndex).compareTo(list.get(parentIndex)) > 0){
                    E temp = list.get(currentIndex);
                    list.set(currentIndex, list.get(parentIndex));
                    list.set(parentIndex, temp);
                }
                else
                    break;
                currentIndex = parentIndex;
            }
        }

        public E remove(){
            if(list.size() == 0) return null;

            E removedObject = list.get(0);
            list.set(0, list.get(list.size() - 1));
            list.remove(list.size() - 1);

            int currentIndex = 0;
            while(currentIndex < list.size()){
                int leftChildIndex = 2 * currentIndex + 1;
                int rightChildIndex = 2 * currentIndex + 2;

                if(leftChildIndex >= list.size()) //这说明当前节点已经是叶子了,这时树已经是堆
                    break;
                int maxIndex = leftChildIndex;
                if(rightChildIndex < list.size()){ //这一段是为了找到左右子节点中最大的节点
                    if(list.get(rightChildIndex).compareTo(list.get(maxIndex))> 0){
                        maxIndex = rightChildIndex;
                    }
                }

                if(list.get(currentIndex).compareTo(list.get(maxIndex)) < 0){
                    E temp = list.get(currentIndex);
                    list.set(currentIndex, list.get(maxIndex));
                    list.set(maxIndex, temp);
                    currentIndex = maxIndex;
                }
                else
                    break; //这时树已经是堆
            }
            return removedObject;
        }
    }

    HeapSort.java代码如下:

    package test;

    public class HeapSort {
        public static <E extends Comparable> void heapSort(E[] list){
            Heap <E> heap = new Heap<E>();

            for(int i = 0; i < list.length; i++)
                heap.add(list[i]);
                for(int i = list.length - 1; i >= 0; i--)
                    list[i] = heap.remove();
        }
        public static void main(String []args){
            Integer [] list = {1,2,3,4,5,6};
        // int [] list = {5, 2, 9, 3, 8, 4, 5, 5, 0, 1, 6, 7};
            for(int i = 0; i < list.length; i++)
            System.out.print(list[i] + " ");
            System.out.print(" ");

            heapSort(list);

            for(int i = 0; i < list.length; i++)
            System.out.print(list[i] + " ");
        }
    }

  • 相关阅读:
    3.13作业 制作网页布局
    3.11 框架和样式表
    表单
    3.8学习记录
    第一次作业
    数据库增删改查
    数据库三大范式
    数据库中的时间戳
    数据库的主键与外键
    登录页面
  • 原文地址:https://www.cnblogs.com/hansonzhe/p/3596030.html
Copyright © 2011-2022 走看看