数据结构与算法(Java版)_堆

完全二叉树叫做堆。

完全二叉树就是最后一个节点之前不允许有不满的节点,就是不允许有空洞。

可以使用数组来做完全二叉树(堆)。

堆分为大顶堆和小顶堆。大顶堆就是根节点上的数字是最大的,小顶堆就是根节点上的数字是最小的堆。

在堆里面的操作包括两种:插入新的节点和删除根节点。

插入新节点的操作时向上渗透。删除根节点的操作是向下渗透。

插入新节点时,把新的节点插入到最后一个位置,然后慢慢向上渗透(和父辈交换)。删除根节点时,把最后一个节点放到根节点上,然后再慢慢向下渗透(和子代交换)。

下面使用Java写一个大顶堆。

package Heap;

public class MaxHeap {
    private int[] heapArray;
    private int maxSize;
    private int currentSize;
    /*构造函数*/
    public MaxHeap(int mx) throws Exception {
        if(mx < 1) throw new Exception("max size must be >=1");
        maxSize = mx;
        currentSize = 0;
        heapArray = new int[maxSize];
    }
    /*向上渗透,index为下标*/
    private void trickleUp(int index){
        int parent = (index - 1) / 2;
        int bottom = heapArray[index];
        while(index>0 && heapArray[parent]<bottom){
            heapArray[index] = heapArray[parent];
            index = parent;
            parent = (parent - 1) / 2;
        }
        heapArray[index] = bottom;
    }
    /*向下渗透*/
    private void trickleDown(int index){
        int largerChild;
        int top = heapArray[index];
        while(index < currentSize / 2){
            int leftChild = 2 * index + 1;
            int rightChild = 2 * index + 2;
            if(rightChild<currentSize && heapArray[leftChild]<heapArray[rightChild])
                largerChild = rightChild;
            else
                largerChild = leftChild;
            if(top >= heapArray[largerChild])
                break;
            heapArray[index] = heapArray[largerChild];
            index = largerChild;
        }
        heapArray[index] = top;
    }
    public boolean IsEmpty(){
        return currentSize == 0;
    }
    public void Push(int num) throws Exception{
        if(currentSize == maxSize) throw new Exception("MaxHeap id full");
        heapArray[currentSize] = num;
        trickleUp(currentSize);
        currentSize++;
    }
    public int Top(){
        return heapArray[0];
    }
    public void Pop(){
        heapArray[0]=heapArray[--currentSize];
        trickleDown(0);
    }
    public static void main(String[] args) throws Exception {
        System.out.println("测试大顶堆");
        MaxHeap maxHeap = new MaxHeap(100);
        System.out.println(maxHeap.IsEmpty());
        maxHeap.Push(20);
        maxHeap.Push(30);
        maxHeap.Push(40);
        System.out.println(maxHeap.Top());
        maxHeap.Push(90);
        maxHeap.Push(80);
        maxHeap.Push(70);
        System.out.println(maxHeap.Top());
        maxHeap.Pop();
        System.out.println(maxHeap.Top());
        maxHeap.Pop();
        System.out.println(maxHeap.Top());
        maxHeap.Pop();
        System.out.println(maxHeap.Top());
    }
}

堆排序就是迭代弹出栈顶元素。

堆排序的时间复杂度是O(nlogn).

原文地址:https://www.cnblogs.com/LoganChen/p/8343783.html

时间: 2024-08-29 20:25:21

数据结构与算法(Java版)_堆的相关文章

数据结构和算法(Java版)

主要内容:(内容来自互联网以及李刚著作的<突破程序员基本功的16课>) 1.数据结构:线性表.栈.队列.树&二叉树 2.算法:常用内部排序(选择.插入.交换.归并) 目录: 1. 线性表(顺序存储.链式存储单链表.双向链表)-------------2014/10/15 2. 栈(顺序栈.链栈)                                        -------------2014/10/15 线性表(顺序存储.链式存储):一对一松耦合关系.(List就是线性

数据结构排序算法Java实现

闲的无聊又拿起了大学的数据结构的书看起来 <数据结构(c语言版)>严蔚敏 吴伟民编著. 里面有几个排序算法,感觉挺好玩的,就想着写出来玩玩. package test.sort; /** * @Title: TODO * @Description: TODO * @author: * @date: 2014-8-10 上午11:20:43 * */ public class quickSort { private static int datas[] = {23,42,12,45,56,63,

MapReduce原理——PageRank算法Java版

Page Rank就是MapReduce的来源,下文是一个简单的计算PageRank的示例. import java.text.DecimalFormat; /**  * Created by jinsong.sun on 2014/7/15.  */ public class PageRankCaculator {     public static void main(String[] args) {         double[][] g = calcG(genS(), 0.85);  

扎金花大小比较算法(Java版)

注:以下算法说明仅限一副牌(不包含大小王)的情况 1.扎金花规则说明(大家都懂的,这里做简单描述): 1)玩家每人3张牌: 2)牌面大小2.3.4.5.6.7.8.9.10(用T表示),J.Q.K.A,大小依次递增: 3)牌的花色有黑桃(用H表示).红心(用X表示).梅花(用M表示).方块(用F表示),大小依次递减: 4)牌有豹子(3张牌数字大小相同).同花顺.同花(此种未实现,有兴趣的玩家可以自己加上,或者欢迎和我交流).顺子.对子.散牌几种类型,大小依次递减: 5)玩家先比牌的类型,如先按照

排序算法Java版,以及各自的复杂度,以及由堆排序产生的top K问题

常用的排序算法包括: 冒泡排序:每次在无序队列里将相邻两个数依次进行比较,将小数调换到前面, 逐次比较,直至将最大的数移到最后.最将剩下的N-1个数继续比较,将次大数移至倒数第二.依此规律,直至比较结束.时间复杂度:O(n^2) 选择排序:每次在无序队列中"选择"出最大值,放到有序队列的最后,并从无序队列中去除该值(具体实现略有区别).时间复杂度:O(n^2) 直接插入排序:始终定义第一个元素为有序的,将元素逐个插入到有序排列之中,其特点是要不断的 移动数据,空出一个适当的位置,把待插

Java数据结构和算法 第二版 课后习题第三章

习题1.bubbleSort.java程序(清单3.1)和BubbleSort专题applet中,in索引变量都是从左到右移动的,直到找到最大数据项并把它移动到右边的out变量外.修改bubbleSort()方法,使它成为双向移动的.这样,in索引先像以前一样,将最大的数据项从左移到右,当它到达out变量位置时,它掉头并把最小的数据项从右移到左.需要两个外部索引变量,一个在右边(以前的out变量),另一个在左边. public static void bubbleSort(int nElem,i

A*(也叫A star, A星)寻路算法Java版

寻路算法有很多种,A*寻路算法被公认为最好的寻路算法. 首先要理解什么是A*寻路算法,可以参考这三篇文章: http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003(英文) http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html(中文) http://www.cnblog

数据结构与算法分析Java版pdf

下载地址:网盘下载 本书是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计).本书把算法分析与最有效率的Java程序的开发有机地结合起来,深入分析每种算法,内容全面.缜密严格,并细致讲解精心构造程序的方法. 原文地址:https://www.cnblogs.com/longgg/p/8419233.html

数据结构之堆栈java版

import java.lang.reflect.Array; /* 具体原理在c++版已经说的很清楚,这里不再赘述, 就提一点:java的泛型具有边界效应,一旦离开作用域立马被替换为object类型,在new泛型数组需要借助反射. */ interface BaseStack<T>{ boolean push(T x); boolean pop(); void clear(); T top();}public class JBStack<T> implements BaseSta

常见的排序算法--java版

个人总结的常见的排序算法 public class Sort { // 1.冒泡:稳定,最优O(n) 最差O(n^2) 平均O(n^2) private static void sort1(int[] arr) { for (int i = 0; i < arr.length; i++) { for (int j = 0; j < arr.length - 1; j++) { if (arr[j] > arr[j + 1]) { int tmp = arr[j]; arr[j] = ar