当前课程知识点:数据结构(Data Structures) >  3. Tree >  3.8 Construction of Heap >  Video

返回《数据结构(Data Structures)》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《数据结构(Data Structures)》慕课在线视频列表

Video课程教案、知识点、字幕

各位同学大家好

前面我们已经学习了堆的存储结构

下面我们将进一步学习到

堆的构造过程

前面我们学了堆的类的定义

其中核心元素就是一个数组Heap

基于这个数组

我们实现了堆中数据元素的存储

在这里我们给出的是

大顶堆maxheap的定义

至于小顶堆的定义也是类似的

下面我们来重点介绍一下

如何实现堆的构造

我们要去使用堆

那么就必须要了解

给定一组数据

我们如何把这组数据组织成为一个堆

从而让数组中的数据满足堆的性质

这个过程我们可以在堆的构造函数中

来去实现堆的构造

我们可以看到这里构造函数有三个参数

第一个是用来指向一个数组的指针h

在这个数组中存储了一组数据

第二个参数num

记录的是数组中的数据的个数

第三个参数max

是指数组的大小

在这个构造函数的开始

我们要对这些属性成员进行赋值

我们采用Heap来去记录数组的位置

用n来去记录数组中数据的个数

用size来去记录数组的大小

然后构造函数最主要的工作

就是要调整数组中的数据

使得他们满足堆的性质

为了实现这个调整

我们定义了一个buildHeap函数

来去实现堆的调整

这个函数将数组中的数据位置进行调整

使得它能满足堆的性质

下面我们通过一些例子

来看一下如何将一组元素

调整成为一个堆

在这里面初始化的时候

这个堆里面

这个数组里面一共有7个元素

在图中我们可以看到

这些数组我们可以把它对应成为

一个完全二叉树

我们可以通过一系列的元素交换

将这个完全二叉树调整成为一个大顶堆

那我们根据大顶堆的性质

任何一个结点的值

都要比它的孩子要大

所以我们可以通过检查这棵二叉树上面

不满足堆性质的结点对

然后把它们进行对调调整

从而把二叉树调整成为一个大顶堆

比如在这个例子里面

数据元素2和4

它们的关系是不满足大顶堆的性质的

所以我们可以把它们进行对调

对调4和1的位置

对调2和1的位置

5和2的位置 5和4的位置

7和3的位置 7和5的位置

6和5的位置

总共我们经过了8次对调调整

最终得到了一个大顶堆

当然这个对调方案它不是唯一的

这个时候我们就需要思考

如何才能够最为有效 有序地

完成堆的构建

一般来说要让事情完成的比较有效

就必须要有一个有序的过程

一个自底向上构建堆的方法

有序有效地完成堆的构建

那我们可以分成以下几个步骤来完成

首先给定一个完全二叉树

我们会将树根的左子树先调整为一个堆

然后第二步

我们会将树根的右子树调整为一个堆

我们再将整一棵树调整成一个堆

在这里前面两个步骤

都是一个递归调整的过程

将其中一个子树调整成为大顶堆

我们这里重点要看一下最后这个步骤

在图中我们给出了相应的例子

当我们树根的左子树和右子树

都已经是大顶堆的情况下

接下来的调整过程

就取决于这个树根结点

如果树根结点是大于等于下面的孩子结点

那么我们就可以停止调整

因为它已经满足了大顶堆的性质

否则的话如果树根结点的值

是小于任何一个孩子结点

那么就违反了大顶堆的性质

因此为了检测堆的性质

我们可以将树根和两个孩子之间的较大值

进行比较

如果树根比较小

那么我们就需要调整

在这个例子中

树根1这个结点

它的两个孩子的较大值是7

由于树根1是小于这个结点的

所以不符合大顶堆的性质

因此我们可以将树根和这个较大的孩子

进行一次交换

这个时候替换下来的树根结点的值

将大于等于孩子的值

从而满足大顶堆的性质

那么针对替换下来的树根结点1

还需要继续地和它的孩子

进行进一步的比较

如果比较大的孩子结点的值

要比树根的要小

那么还要继续进行替换

这个比较和替换的过程

会从树根一直持续下来

直到整一棵树满足大顶堆的性质

整个过程中原树根结点

会从树根开始通过不断的比较 交换

直到停留到某个合适的位置

这整一个过程

我们称为筛选过程

英文叫做Sift down

我们接下来来看一下siftdown函数的实现

siftdown函数里面它有个参数pos

指的是树根结点在数组中的下标位置

siftdown的过程

就是将树根结点从上往下

调整到一个合适的位置的过程

在调整的过程中

我们要将pos位置的结点

和它的孩子结点进行比较

这里我们首先让j指向pos位置结点的

左孩子结点

让rc指向它的右孩子结点

如果这个右孩子是存在的

并且左孩子结点小于右孩子结点

那么我们就用j

来去指向右孩子结点

这样一来j始终指向的是

两个孩子里面的比较大的那个结点

所以我们这里将pos所指向的结点

和这个比较大的孩子进行比较

如果pos所指向的结点

要大于等于这个比较大的孩子

那么我们就说明它满足大顶堆的性质

我们就可以停止堆的调整

否则的话我们要将数据元素进行对调

这里的swap函数

就是将堆中数组中的pos位置的值

和j位置的值进行对调调整

当完成这个交换之后

我们需要去更换pos变量

让它重新指向交换之后的

根结点所在的位置

下面这个比较和对调调整的过程

是一个迭代持续的过程

我们需要将pos位置的结点

继续和它的孩子进行比较

所以我们需要一个循环语句

只要pos位置的结点

没有被调整到叶子的位置

那么这个循环将会持续下去

整个过程中有两个退出条件

一个是循环的退出条件

也就是pos位置的结点

被调整到叶子的位置

另外一个退出条件

是pos位置的结点

要大于等于它的孩子结点

满足堆的性质

那么这个循环也会退出

这个程序的循环语句执行的次数

等同于结点的交换次数

而我们知道交换的次数

在这里面是不会超过整棵树的高度的

对于结点数目为n的完全二叉树来说

它的高度是Θ(log n)

所以循环语句执行的次数也是Θ(log n)

也就是说siftdown函数的时间复杂度

是Θ(log n)

基于siftdown函数

我们就可以实现自底向上的

构建堆的过程

我们从最后的结点开始

逐个结点进行考察

对不满足堆性质的结点进行调整

那么在这里排到最后面的是叶子结点

因为叶子是没有孩子的

所以并没有违反堆的性质

不需要进行调整

所以我们首先从

最后一个中间结点开始进行调整

我们可以通过调用siftdown筛选过程

对这个结点进行调整

比如说在途中这个例子里面

2号结点我们需要对它进行调整

当然对2号结点

调用siftdown调整完毕之后

我们继续对前面的结点

进一步地进行调整

我们可以继续地对1号结点调用siftdown

然后再对0号结点调用siftdown

当我们对0号结点

也就是根结点调用siftdown之后

那么整一个二叉树

将会被我们调整成为一个大顶堆

所以我们这里归结一下

堆的构建过程

就是一个从后往前

对每一个中间结点

调用siftdown函数的过程

那么最终我们就可以得到一个大顶堆

相应地我们就可以去实现

这个堆的构建函数buildHeap

这个函数的实现过程其实比较简单

就是要去实现一个循环语句

对每一个中间结点

都去调用siftdown函数

那么其中最后的这个中间结点

它的数组下表是n/2-1

这是由于这个最后的中间结点

它是最后一个叶子结点

也就是n-1号结点的父亲

所以它的数组下标是

n-1-1然后对2整除

也就是n/2-1

所以for循环我们将从最后一个中间结点

n/2-1这个位置

一直到树根结点0号位置

对每一个中间结点

都去调用这个siftdown函数

最后我们就可以完成堆的调整

从而我们得到一个大顶堆

最后我们来分析一下堆的构建函数

buildHeap函数它的代价

我们可以看到堆的构建过程中

主要计算时间都消耗在树上的结点

相互之间比较以及交换

那么我们来分析一下堆的构建过程

整个过程中结点的比较和交换的次数

我们对这样的一棵二叉树

来进行逐层分析

由于buildHeap的函数

是从后往前进行堆的调整

所以我们先看最下层这个叶子结点

对这一层的结点我们是不需要调整的

所以对调交换的次数是0

那么对倒数第二层的结点来说

每一个结点最多会发生一次比较和交换

而这一层结点的数目

我们是可以证明约等于

结点总数的四分之一

也就是n/4

所以在这一层上

结点的比较和交换的总数是1×n/4

而对于倒数第三层的结点来说

每一个结点最多会发生两次比较和交换

而这一层的结点数目是n/8

所以在这一层上面

结点的比较交换的总数是2×n/8

如果我们对所有的层都进行编号

用i来去表示层的编号

那被每一层上面结点交换的总次数

我们都可以统一地表达成为

(i-1)n/2^i

所以整一棵树上面

结点比较和交换的总次数

我们可以归结为这样的一个求和公式

根据Θ的定义

我们最终可以得到这个总代价是Θ(n)

好的 我们这节课讲到这里

数据结构(Data Structures)课程列表:

1. Introduction

-1. Introduction--1.1 Introduction of Data

-1.1 Introduction of Data Structure

--Introduction of Data Structure

-1.2 Data Structure and A

-1.2 Data Structure and Algorithm

--Video

-1.3 Asymptotic Analysis

-1.3 Asymptotic Analysis

--Video

-1.4 Simplifying Rules of

-1.4 Simplifying Rules of Asymptotic Analysis

--Video

2. List

-2.1 Introduction of List

-2.1 Introduction of List

--Video

-2.2 Array based List

-2.2 Array based List

--Video

-2.3 Insertion Operation on Array

-2.3 Insertion Operation on Array based List

--Video

-2.4 Remove Operation on Array based List

-2.4 Remove Operation on Array based List

--Video

-2.5 Linked list

-2.5 Linked list

--Video

-2.6 Insertion Operation on Linked list

-2.6 Insertion Operation on Linked list

--Video

-2.7 Remove Operation on Linked list

-2.7 Remove Operation on Linked list

--Video

-2.8 SetPos Operation on Linked list

-2.8 SetPos Operation on Linked list

--Video

-2.9 Stack

-2.9 Stack

--Video

-2.10 Application of Stack

--Video

-2.11 Queue

-2.11 Queue

--Video

3. Tree

-3.1 Definition of Binary Tree

-3.1 Definition of Binary Tree

--Video

-3.2 Implementation of Binary Tree

-3.2 Implementation of Binary Tree

--Video

-3.3Traversal

-3.3 Traversal

--Video

-3.4 Binary Search Tree

-3.4 Binary Search Tree

--Video

-3.5 Search on BST

-3.5 Search on BST

--Video

-3.6 Insertion on BST

-3.6 Insertion on BST

--Video

-3.7 Introduction of Heap

-3.7 Introduction of Heap

--Video

-3.8 Construction of Heap

-3.8 Construction of Heap

--Video

-3.9 Operations on Heap

--Video

-3.10 General Tree

--Video

4. Search

-4.1 Definition of Searching

--Video

-4.2 Searching of Sorted Array

-4.2 Searching of Sorted Array

--Video

-4.3 Definition of Hash Table

--Video

-4.4 Collision in Hash Table

-4.4 Collision in Hash Table

--Video

-4.5 Extension of Linear Probing

--Video

-4.6 Insertion Operation of Hash Table

--Video

-4.7 Search Operation of Hash Table

-4.7 Search Operation of Hash Table

--Video

5. Index

-5.1 Introduction of Index

--Video

-5.2 Linear Index

-5.2 Linear Index

--Video

-5.3 2-3 tree index

-5.3 2-3 tree index

--Video

-5.4 Implementation of 2-3 tree

-5.4 Implementation of 2-3 tree

--Video

-5.5 B-Tree

-5.5 B-Tree

--Video

-5.6 Insertion Operation on B+ Tree

--Video

-5.7 Deletion Operation on B+ Tree

--Video

6. Graph

-6.1 Definition of Graph

--Video

-6.2 Implementation of Graph

--Video

-6.3 Adjacency Matrix

--Video

-6.4 Adjacency List

--Video

-6.5 Graph Traversal - DFS

--Video

-6.6 Graph Traversal - BFS

--Video

-6.7 Topological Sort

--Video

-6.8 Shortest Path Problem

--Video

-6.9 Single Source Shortest Path

--Video

-6.10 Dijkstra Algorithm

--Video

7. Sorting

-7.1 Sorting Problem

--Video

-7.2 Insertion Sort

--Video

-7.3 Selection Sort

--Video

-7.4 Bubble Sort

--Video

-7.5 Shell Sort

--Video

-7.6 Quick Sort

--Video

-7.7 Heap Sort

--Video

-7.8 Comparison

--Video

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。