美文网首页
数据结构-树-堆-基础

数据结构-树-堆-基础

作者: TioSun | 来源:发表于2020-08-27 18:37 被阅读0次

堆是一种特殊的树,那么堆有什么样的特点呢?

  1. 堆是一颗完全二叉树
  2. 堆必须满足其任意节点都要大于等于(或小于等于)其左右子节点(大于等于还是小于等于取决于要构建一个大顶堆还是小顶堆

堆的实现

因为堆是一颗完全二叉树,我们知道完全二叉树是很适合用数组存储的(因为不会有空间浪费)

堆的插入

简单的插入动作会破坏堆的特性,所以我们要在数据插入后,重新根据堆的特性重新调整数组使其重新符合堆的特性,这个过程叫做堆化。
堆化分为自上而下和自下而上,插入一般是自下而上的堆化过程。
以大顶堆为例子,插入的逻辑其实就是在堆的最后(其实就是数组里的第一个空的位置)插入一个元素,然后不停的和父节点比较,如果插入数据大于父节点,则和父节点交换,直到无法交换为止


堆的插入
package tree;

/**
 * @author TioSun
 */

public class Heap {
    /**
     * 数组,从下标1开始存储数据
     */
    private int[] a;
    /**
     * 堆可以存储的最大数据个数
     */
    private int capacity;
    /**
     * 堆中已经存在的数据个数
     */
    private int count;

    public Heap(int capacity) {
        this.a = new int[capacity + 1];
        this.capacity = capacity;
        this.count = 0;
    }

    public void insert(int data) {
        // 判断是否堆满
        if (count >= capacity) {
            return;
        }
        ++count;
        a[count] = data;
        // 表示新插入数据的当前位置
        int i = count;
        // 自下而上堆化
        while (i/2 > 0 && a[i] > a[i/2]) {
            int temp = a[i];
            a[i] = a[i/2];
            a[i/2] = temp;
            i = i/2;
        }
    }
}

删除堆顶元素

删除堆顶元素的一般做法是用最后一个元素去替换堆顶元素,然后自上而下堆化。
以大顶堆为例,自上而下堆化的步骤是将堆顶元素和左右子节点进行比较,如果小于左右子节点中的其中一个节点,则交换,如果小于左右两个子节点,则和左右子节点中的大的那个交换,重复该步骤,直到无法交换
参照下图,删除堆顶元素41的步骤如下

  1. 将堆顶元素41用29替换
  2. 将29和27、39比较
  3. 29和39交换
  4. 29和33、36比较
  5. 29和36交换
  6. 29和26比较,无法交换,堆化结束


    大顶堆
package tree;

/**
 * @author TioSun
 */

public class Heap {
    /**
     * 数组,从下标1开始存储数据
     */
    private int[] a;
    /**
     * 堆可以存储的最大数据个数
     */
    private int capacity;
    /**
     * 堆中已经存在的数据个数
     */
    private int count;

    public Heap(int capacity) {
        this.a = new int[capacity + 1];
        this.capacity = capacity;
        this.count = 0;
    }

    public void removeTop() {

        if (count == 0) {
            return;
        }
        // 将堆顶元素用最后一个元素替换
        a[1] = a[count];
        count--;
        // 表示替换后的数据的当前位置
        int i = 1;
        while (true) {
            // 需要交换的目标位置,先设为当前位置以表示无需交换
            int targetIndex = i;
            // 尝试和左子节点比较
            if (i * 2 < count && a[i] < a[i * 2]) {
                // 将交换位置暂定为左子节点
                targetIndex = i * 2;
            }
            // 尝试和右子节点比较
            if (i * 2 + 1 < count && a[targetIndex] < a[i * 2 + 1]) {
                targetIndex = i * 2 + 1;
            }
            if (targetIndex == i) {
                // 无需交换
                break;
            }
            // 与待交换位置的元素交换
            int temp = a[i];
            a[i] = a[targetIndex];
            a[targetIndex] = temp;
            
            i = targetIndex;

        }
    }
}

相关文章

  • 数据结构-树-堆-基础

    堆是一种特殊的树,那么堆有什么样的特点呢? 堆是一颗完全二叉树 堆必须满足其任意节点都要大于等于(或小于等于)其左...

  • 《数据结构与算法之美》01——系统高效地学习数据结构与算法

    20个最常用的、最基础的数据结构与算法。 数据结构:数组、链表、栈、队列、散列表、二叉树、堆、跳表、图、Trie树...

  • 舒服!阿里P9架构师熬夜梳理的2020版Java成神之路指南

    1.计算机基础: 1.1数据结构基础: 主要学习: 1.向量,链表,栈,队列和堆,词典。熟悉 2.树,二叉搜索树。...

  • 大顶堆的实现.md

    大顶堆的实现.md 大顶堆介绍   大顶堆的基础结构就是完全二叉树, 是一种基础的数据结构, 其特点是根节点是最大...

  • 简单数据结构(队列 栈 树 堆 )

    基础知识 基本概念 常见数据结构 栈和队列 栈Stack 队列Queue 树和堆 树的定义 树(tree)是包含n...

  • 数据结构 - 概要

    数组 链表 堆/栈/队列 树 数据结构 - 二叉树数据结构 - 二叉查找树数据结构 - 平衡二叉树数据结构 - A...

  • 堆结构的实现

    堆的定义: 这里的堆是指一种数据结构(或数据结构属性),非指堆内存。堆属性用二叉树来体现,具有堆属性的数据结构才可...

  • 堆排序

    一些基础知识 学习堆排序,总要了解堆的数据结构吧,了解堆又需要了解二叉树的基本知识,了解二叉树要先知道树是个什么东...

  • 数据结构中堆、栈和队列的理解

    一、堆 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树。所以堆在数据结构...

  • iOS堆、栈和队列

    堆 堆是一种经过排序的树形数据结构,每个节点都有一个值,通常我们所说的堆的数据结构是指二叉树。所以堆在数据结构中通...

网友评论

      本文标题:数据结构-树-堆-基础

      本文链接:https://www.haomeiwen.com/subject/qivfsktx.html