数据结构--堆

Posted 可持续化发展

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--堆相关的知识,希望对你有一定的参考价值。

目录

堆的定义

堆的分类

 堆的插入

堆的删除

用数组来表示完全二叉树

创建堆

 插入元素

 获取堆顶元素

 删除元素

 获取堆的长度

 最小堆

 最大堆

 堆排序


堆的定义

 是一种特别的二叉树,满足以下条件的二叉树,可以称之为 

  1. 完全二叉树;
  2. 每一个节点的值都必须 大于等于或者小于等于 其孩子节点的值。

堆 具有以下的特点:

可以在 O(logN) 的时间复杂度内向 堆 中插入元素;
可以在 O(logN) 的时间复杂度内向 堆 中删除元素;
可以在 O(1)的时间复杂度内获取 堆 中的最大值或最小值。

堆的分类

堆 有两种类型:最大堆 和 最小堆。

最大堆:堆中每一个节点的值 都大于等于 其孩子节点的值。所以最大堆的特性是 堆顶元素(根节点)是堆中的最大值。

最小堆:堆中每一个节点的值 都小于等于 其孩子节点的值。所以最小堆的特性是 堆顶元素(根节

点)是堆中的最小值。

 堆的插入

现在有一个堆,我们分为3步:

1.先判断是不是最大堆 或最小堆

2.按完全二叉树的插入操作,将节点插入堆中

3.对堆进行调整,使其满足最大堆或最小堆的特性

 

 

 

堆的删除

删除操作是指在  中删除堆顶元素。元素删除之后, 依旧需要维持它的特性。

堆的删除分为以下几步:

1、从上到下,从左到右,找到完全二叉树的最后一个节点,将最后一个节点的值覆盖堆顶元素,然后删除最后一个节点。

2、开始调整堆,使其满足最大堆或最小堆的特性。

 

 

 

 

 

 

可以用数组实现堆。我们将堆中的元素以二叉树的形式存入在数组中。以下代码将使用数组实现整数类型的「最大堆」和「最小堆」

用数组来表示完全二叉树

 

 节点的个数

创建堆

创建 堆 指的是初始化一个堆实例。所有堆方法的前提必须是在堆实例上进行操作。换句话说,我们必须要首先创建一个 堆 实例,然后才能使用 堆 的常用方法。在创建 堆 的过程中,我们也可以同时进行 堆化 操作。堆化 就是将一组数据变成 堆 的过程。

时间复杂度: O(N)。

空间复杂度: O(N)。

// Java中的堆可以用优先队列(PriorityQueue)来表示
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.Arrays;
// 创建一个空的最小堆
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
// 创建一个空的最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());

// 创建带初始值的「堆」, 或者称为「堆化」操作,此时的「堆」为「最小堆」
PriorityQueue<Integer> heapWithValues= new PriorityQueue<>(Arrays.asList(3,1,2));

 插入元素

插入操作指的是向 堆 中插入一个新元素。值的注意的是,新元素插入完毕后,堆 依旧需要维持它的特性。

时间复杂度: O(log N)。

空间复杂度: O(1)。

// 最小堆插入元素
minHeap.add(1);
// 最大堆插入元素
maxHeap.add(1);

 获取堆顶元素

最大堆 的堆顶元素是 堆 中的最大值,最小堆 的堆顶元素是 堆 中的最小值。因此,堆顶元素是 堆 中最重要的元素。

时间复杂度: O(1)。

空间复杂度:O(1)。

// 最小堆获取堆顶元素,即最小值
minHeap.peek();
// 最大堆获取堆顶元素,即最大值
maxHeap.peek();

 删除元素

删除堆顶元素后,值得注意的是,堆 依旧需要维持它的特性。此时,新的堆顶元素也是当前堆中的最大值(如果堆是 最大堆)或最小值(如果堆是 最小堆)。

时间复杂度:O(log N)。

空间复杂度:O(1)。

// 最小堆删除堆顶元素
minHeap.poll();
// 最大堆删除堆顶元素
maxheap.poll();

 获取堆的长度

 

堆 的长度可以用来判断当前堆的大小,也可以用来判断当前堆是否还有元素。如果当前堆中没有元素,则 堆 的长度为 0。

时间复杂度:O(1)

空间复杂度:O(1)

// 最小堆的长度
minHeap.size();
// 最大堆的长度
maxHeap.size();
// 注意:Java中判断堆是否还有元素,除了检查堆的长度是否为0外,还可以使用isEmpty()方法。
// 如果堆中没有元素,则isEmpty()方法返回true。
// 如果堆中还有元素,则isEmpty()方法返回false。

 最小堆

import java.util.*;

public class MinHeap {
	public static void main(String[] args) {
		//创建一个最小堆实例
		PriorityQueue<Integer> minHeap = new PriorityQueue<>();
		minHeap.add(3);
		minHeap.add(1);
		minHeap.add(2);
		//查看最小堆的所有元素,结果为:[1,3,2]
		System.out.println("minHeap:"+ minHeap.toString());
		//获取最小堆的堆顶元素
		int peekNum = minHeap.peek();
		//结果为:1
		System.out.println("peekNum:"+ peekNum);
		//删除最小堆的堆顶元素
		int pollNum = minHeap.poll();
		//结果为 1
		System.out.println("pollNum:"+ pollNum);
		//查看删除1后最小堆的堆顶元素,结果为 2
		System.out.println("peekNum:"+ minHeap.peek());
		//查看所有元素 [2, 3]
		System.out.println("minHeap:"+ minHeap.toString());
		//查看最小堆的元素个数,最小堆的长度 2
		int heapSize = minHeap.size();
		System.out.println("minHeap Size:"+ heapSize);
		//判断最小堆是否还有元素
		boolean isEmpty = minHeap.isEmpty();
		System.out.println("isEmpty:"+ isEmpty);		
	}   
}

 最大堆

import java.util.*;


public class MaxHeap {
	public static void main(String[] args) {
		//创建一个最小堆实例
		PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
		maxHeap.add(3);
		maxHeap.add(1);
		maxHeap.add(2);
		//查看最小堆的所有元素,结果为:[3, 1, 2]
		System.out.println("maxHeap:"+ maxHeap.toString());
		//获取最小堆的堆顶元素
		int peekNum = maxHeap.peek();
		//结果为:3
		System.out.println("peekNum:"+ peekNum);
		//删除最小堆的堆顶元素
		int pollNum = maxHeap.poll();
		//结果为 3
		System.out.println("pollNum:"+ pollNum);
		//查看删除1后最小堆的堆顶元素,结果为 2
		System.out.println("peekNum:"+ maxHeap.peek());
		//查看所有元素 [2, 1]
		System.out.println("maxHeap:"+ maxHeap.toString());
		//查看最小堆的元素个数,最小堆的长度 2
		int heapSize = maxHeap.size();
		System.out.println("maxHeap Size:"+ heapSize);
		//判断最小堆是否还有元素
		boolean isEmpty = maxHeap.isEmpty();
		System.out.println("isEmpty:"+ isEmpty);		
	}   
}

 堆排序

理论:堆排序指的是利用堆的数据结构对一组无序元素进行排序。

最小堆 排序算法步骤如下:

  1. 将所有元素堆化成一个 最小堆 ;
  2. 取出并删除堆顶元素,并将该堆顶元素放置在存储有序元素的数据集 T 中;
  3. 此时,堆 会调整成新的 最小堆;
  4. 重复 3 和 4 步骤,直到 堆 中没有元素;
  5. 此时得到一个新的数据集 T,其中的元素按照 从小到大 的顺序排列。

最大堆排序算法步骤如下:

  1. 将所有元素堆化成一个 最大堆;
  2. 取出并删除堆顶元素,并将该堆顶元素放置在存储有序元素的数据集 T 中;
  3. 此时,堆 会调整成新的 最大堆;
  4. 重复 3 和 4 步骤,直到 堆 中没有元素;
  5. 此时得到一个新的数据集 T,其中的元素按照从大到小的顺序排列。

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于数据结构--堆的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 OnStop() 回收所有数据并使用保留片段?

算法排序之堆排序

是否可以在OnStop()上回收所有数据并使用保留片段?

Rail片段缓存如何使您的应用受益,即阻止数据库调用?

方法与对象内存分析

VSCode自定义代码片段5——HTML元素结构