应用堆实现一个优先队列
- 格式:doc
- 大小:402.50 KB
- 文档页数:25
优先队列升序写法首先,优先队列是一种特殊的队列,其中每个元素都具有一个与之关联的优先级。
当出队时,优先级高的元素先出队,而优先级低的元素则稍后出队。
在升序优先队列中,优先级较高的元素是值越小的元素。
下面,我们将会用中文来讲述升序优先队列的实现方式。
首先,让我们来看看优先队列升序的实现思路:1. 用数组或链表等数据结构来存储元素。
2. 当元素入队时,按照优先级顺序插入到合适的位置。
3. 当元素出队时,取出优先级最高的元素,并删除它。
现在,让我们来详细看看优先队列升序的具体实现方法。
1. 数组实现在使用数组来实现优先队列时,我们需要在数组中存储元素及其优先级。
当元素入队时,我们需要遍历数组并找到第一个比当前元素优先级高的位置,然后将当前元素插入到该位置。
当元素出队时,我们只需要删除数组的最后一个元素即可。
2. 链表实现在使用链表来实现优先队列时,我们需要在链表中存储元素及其优先级。
当元素入队时,我们需要遍历链表并找到第一个比当前元素优先级高的位置,然后将当前元素插入到该位置。
当元素出队时,我们只需要删除链表的第一个元素即可。
3. 堆实现在使用堆来实现优先队列时,我们需要在堆中存储元素及其优先级。
当元素入队时,我们需要插入到堆的末尾,然后进行上浮操作,将元素插入到合适的位置。
当元素出队时,我们需要删除堆顶元素,然后进行下沉操作,将堆中的其他元素重新排列成堆的形式。
无论使用哪种实现方式,都需要注意以下几点:1. 在插入操作时,要确保元素始终按照优先级顺序排列。
2. 在删除操作时,要确保始终取出优先级最高的元素。
3. 在处理异常情况时,要确保代码的健壮性。
总之,在实现优先队列升序时,我们需要注意以下几点:1. 根据具体应用场景选择合适的实现方式。
2. 在插入和删除操作时,要确保始终遵循优先级规则。
3. 考虑到空间和时间复杂度,合理调整数据结构的大小。
以上是升序优先队列的实现方法,希望能对读者有所帮助。
堆排序的几种方法堆排序是一种基于堆数据结构的排序算法,具有稳定且时间复杂度为O(nlogn)的特点。
本文将介绍堆排序的几种方法,包括建堆和调整堆两个关键步骤。
一、建堆建堆是堆排序的第一步,其目的是将无序的数组构建成一个堆。
堆是一种完全二叉树,分为大顶堆和小顶堆两种类型。
在大顶堆中,每个节点的值都大于或等于其子节点的值;而在小顶堆中,每个节点的值都小于或等于其子节点的值。
建堆的方法有多种,其中最常用的是从最后一个非叶子节点开始,依次向上调整每个节点的位置,直到根节点。
具体步骤如下:1. 从最后一个非叶子节点开始,向上遍历每个节点。
2. 对于当前节点,比较其与左右子节点的大小关系,如果子节点较大(或较小),则将当前节点与子节点交换位置。
3. 重复步骤2,直到当前节点满足堆的性质,或者到达叶子节点。
二、调整堆建堆完成后,数组的第一个元素一定是堆中的最大(或最小)值。
为了得到有序的数组,需要将第一个元素与最后一个元素交换位置,并对剩余元素进行堆调整。
这样,每次交换后,最大(或最小)值就会被放置在正确的位置上。
调整堆的方法有多种,其中最常用的是从根节点开始,依次向下调整每个节点的位置,直到叶子节点。
具体步骤如下:1. 将第一个元素与最后一个元素交换位置。
2. 缩小堆的范围,即排除已经有序的元素。
3. 对剩余元素进行堆调整。
从根节点开始,比较其与左右子节点的大小关系,如果子节点较大(或较小),则将当前节点与子节点交换位置。
4. 重复步骤3,直到当前节点满足堆的性质,或者到达叶子节点。
三、堆排序的优化方法除了基本的建堆和调整堆方法外,还有一些优化方法可以提高堆排序的效率。
以下是几种常见的优化方法:1. 堆的初始化:在建堆之前,先对数组进行预处理,将数组中的元素调整为局部有序,可以减少后续建堆的时间复杂度。
2. 堆的调整:在调整堆的过程中,可以使用迭代的方式代替递归,以减少函数调用的开销。
3. 堆的选择:在每次交换堆顶元素和最后一个元素后,可以选择将最后一个元素排除在堆的范围之外,从而减少调整堆的次数。
数据结构(⼋):优先队列-最⼤最⼩优先⼀、优先队列的概述 在前⾯的数据结构(三):线性表-栈,队列中记录到,队列是先进先出的结构,元素在队列末端添加,在队列前头删除,若使⽤该队列的数据结构,则当要找出队列中的最⼤最⼩值时,需要遍历队列 对每个元素做⽐较后得出,这样在实际的⽣产应⽤中效率是很低的,这时就需要有⼀种队列,能快捷的获取队列中的最⼤或最⼩值,叫做优先队列。
使⽤优先队列保存数据元素,能快速的获取队列的最⼤或最⼩值,⽐如计算机中有多个排队的任务,但是需要按照优先级⼀⼀执⾏,此时优先队列的优势便得到了体现,在前⼀章对堆的记录中 我们发现堆能快速的找到最⼤或最⼩值并删除,符合优先队列的应⽤场景,因此本章我们使⽤堆来实现最⼤,最⼩优先队列和索引优先队列⼆、最⼩优先队列 1、最⼩优先队列实际就是⼀个⼩顶堆,即每次插⼊堆中的元素,都存储⾄堆末端,通过上浮操作⽐较,⼩于⽗节点则和⽗节点交换元素,直到根结点为⽌,这样就形成了⼀个⼩顶堆。
2、在获取最⼩值时,由于堆是数组的结构,只需获取根结点的值,即数组下标为1的值即可。
3、获取最⼩值并删除,则可以交换根结点和尾结点,之后删除尾结点,并对根结点进⾏下沉操作,保证每个⽗节点都⼩于两个左右⼦树即可public class MinPriorityQueue<T extends Comparable<T>> {// 初始化堆private T[] items;// 初始化个数private int N;/*** 返回优先队列⼤⼩*** @return*/public int size() {return N;}/*** 队列是否为空** @return*/public boolean isEmpty() {return N==0;}/*** 构造⽅法,传⼊堆的初始⼤⼩** @param size*/public MinPriorityQueue(int size) {items = (T[]) new Comparable[size + 1]; N = 0;}/*** 判断堆中索引i处的值是否⼩于j处的值** @param i* @param j* @return*/private boolean bigger(int i, int j) {return items[i].compareTo(items[j]) > 0; }/*** 元素位置的交换** @param col* @param i* @param j*/private void switchPos(int i, int j) {T temp = items[i];items[i] = items[j];items[j] = temp;}/*** 删除堆中最⼤的元素,并且返回这个元素 ** @return*/public T delMin() {// 获取根结点最⼤值T minValue = items[1];// 交换根结点和尾结点switchPos(1, N);// 尾结点置空items[N] = null;// 堆数量减1N--;// 根结点下沉sink(1);return minValue;}/*** 往堆中插⼊⼀个元素t** @param t*/public void insert(T t) {items[++N] = t;swim(N);}/*** 使⽤上浮算法,使堆中索引k处的值能够处于⼀个正确的位置 ** @param k*/private void swim(int k) {while (k > 1) {if (bigger(k / 2, k)) {switchPos(k, k /2);}k = k / 2;}}/*** 使⽤下沉算法,使堆中索引k处的值能够处于⼀个正确的位置 ** @param k*/private void sink(int k) {while (2 * k <= N) {int min;// 存在右⼦结点的情况if (2 * k + 1 <= N) {if (bigger(2 * k, 2 * k + 1)) {min = 2 * k + 1;} else {min = 2 * k;}} else {min = 2 * k;min = 2 * k;}// 当前结点不⽐左右⼦树结点的最⼩值⼩,则退出if (bigger(min, k)) {break;}switchPos(k, min);k = min;}}public static void main(String[] args) {String[] arr = { "S", "O", "R", "T", "E", "X", "A", "M", "P", "L", "E" };MinPriorityQueue<String> minpq = new MinPriorityQueue<>(20);for (String s : arr) {minpq.insert(s);}String del;while (!minpq.isEmpty()) {del = minpq.delMin();System.out.print(minpq.size());System.out.println(del + ",");}}}三、最⼤优先队列 1、最⼤优先队列实际就是⼀个⼤顶堆,即每次插⼊堆中的元素,都存储⾄堆末端,通过上浮操作⽐较,⼤于⽗节点则和⽗节点交换元素,直到根结点为⽌,这样就形成了⼀个⼤顶堆。
二叉堆构建及应用方法全面讲解二叉堆是一种特殊的二叉树结构,具有以下两个性质:1. 完全二叉树:除了最后一层,其他层的节点都是满的,并且最后一层的节点从左到右依次填满。
2. 堆序性质:对于最大堆,父节点的值大于等于其子节点的值;对于最小堆,父节点的值小于等于其子节点的值。
本文将全面讲解二叉堆的构建和应用方法,并通过实例介绍其具体应用场景。
一、二叉堆的构建方法1. 数组表示法:将二叉堆存储在一个数组中,通过以下方式实现对应关系:- 对于节点i,它的左子节点为2i+1,右子节点为2i+2。
- 对于节点i,它的父节点为(i-1)/2。
2. 初始化二叉堆:通过给定的数组构建一个二叉堆,可以使用下面的方法:- 从最后一个非叶子节点开始,依次向上调整节点位置,使得整个树满足堆序性质。
- 调整节点位置的方法是,将节点与其子节点进行比较,并交换位置。
二、二叉堆的应用方法1. 堆排序:堆排序是利用二叉堆进行排序的一种排序算法。
具体步骤如下:- 构建一个最大堆。
- 将堆顶元素与最后一个元素交换,并将最后一个元素从堆中排除。
- 对剩余元素重新进行堆化操作。
- 重复上述步骤,直到堆中只剩下一个元素,即完成排序。
2. 优先队列:优先队列是一种特殊的队列,元素按照一定的优先级顺序进行排列。
二叉堆可以用来实现优先队列,具体操作如下: - 插入操作:将新元素插入到二叉堆的末尾,然后通过上浮操作将其调整到合适的位置。
- 删除操作:将堆顶元素与最后一个元素交换,然后通过下沉操作将堆顶元素调整到合适的位置。
三、二叉堆的应用场景1. Top K 问题:通过维护一个大小为 K 的最小堆,在遍历数据时保持堆中元素是当前最大的 K 个元素,可以解决 Top K 问题。
2. 堆中的中位数:将数据分成两部分,一部分较小的元素存放在最大堆中,一部分较大的元素存放在最小堆中,可以快速求解中位数。
3. Dijkstra 算法:在求解单源最短路径问题时,使用最小堆来维护待处理的节点集合,每次选择最小路径的节点进行拓展。
优先队列的实现(⼤根堆,⼩根堆) 本博客不讲解具体的原理,仅仅给出⼀种优先队列较为⼀般化的,可重⽤性更⾼的⼀种实现⽅法。
我所希望的是能过带来⼀种与使⽤STL相同的使⽤体验,因为学习了STL源码之后深受STL代码的影响,对每个ADT都希望能过给出⼀种⾼效,可重⽤,更⼀般的实现⽅法,即使我的代码在STL的priority_queue⾯前仅仅只是三流⽔平,但也⾜够吧⼆叉堆这种数据结构演绎好了。
为了更⼀般化,我抛弃C语⾔的函数指针,改⽤STL相同的仿函数来实现更加⽅便的⾃定义优先级⽐较函数,于此同时我也兼容了已有类型的原有优先级⽐较仿函数。
⾸先给出maxPriorityQueue的ADT以及默认的优先级⽐较仿函数,默认为⼤根堆,⼩根堆重载优先级⽐较仿函数即可。
#ifndef MAXPRIORITYQUEUE_H#define MAXPRIORITYQUEUE_H#include <cstring>template<class T>struct Compare {bool operator () (const T& a, const T& b) {return a < b;}};template<>struct Compare<char*> {bool operator () (char* s1, char* s2) {return strcmp(s1, s2) < 0;}};template<class T>class maxPriorityQueue {public:~maxPriorityQueue() {}virtual bool empty() const = 0;virtual int size() const = 0;virtual T& top() = 0;virtual void pop() = 0;virtual void push(const T& theElement) = 0;};#endif 对于ADT的设计与实现,在C++中,相应ADT的纯虚类是必不可少的,它是ADT的逻辑定义,是设计数据结构的基础,上述代码给出了maxPriorityQueue的定义以及默认优先级⽐较仿函数,对于仿函数的使⽤⽅法,可在下⾯的maxHeap类中找到。
二叉堆和优先队列高效实现堆排序和Dijkstra算法堆排序和Dijkstra算法是计算机科学中常见且高效的算法。
它们的实现中常用到二叉堆和优先队列的数据结构。
本文将介绍二叉堆和优先队列的概念,以及它们在堆排序和Dijkstra算法中的应用。
一、二叉堆二叉堆是一种特殊的完全二叉树,满足以下两个性质:1. 结构性质:除最后一层外,每一层都是满的,最后一层从左到右填入节点。
2. 堆序性质:对于任意节点i,其父节点值小于等于其子节点的值。
二叉堆有两种类型:大顶堆和小顶堆。
大顶堆中,父节点的值大于等于其子节点;小顶堆中,父节点的值小于等于其子节点。
二叉堆的根节点即堆中的最值。
二、优先队列优先队列是一种可以快速访问和删除最值元素的数据结构。
它支持两个主要操作:1. 插入操作:将元素按照一定的优先级插入队列中。
2. 弹出操作:弹出队列中的最值元素。
优先队列可以用二叉堆实现,其中小顶堆用于实现最小优先队列,大顶堆用于实现最大优先队列。
通过保持堆序性质,我们可以在O(logn)的时间复杂度内完成插入和弹出的操作。
三、堆排序堆排序是一种高效的排序算法,基于二叉堆数据结构。
其主要步骤如下:1. 构建最大堆:将待排序序列构建成一个最大堆。
2. 交换堆顶元素和最后一个元素:将最大堆的堆顶元素与最后一个元素交换,此时最大值被固定在了最后。
3. 调整堆:调整剩余元素构建一个新的最大堆。
4. 重复步骤2和步骤3,直到剩余元素只有一个。
堆排序的时间复杂度为O(nlogn),且具有原地排序的优点,但是不稳定。
四、Dijkstra算法Dijkstra算法是一种解决单源最短路径问题的贪心算法。
其核心思想是利用优先队列选择当前最短路径的顶点来遍历附近的节点,并更新到达这些节点的最短距离。
其主要步骤如下:1. 创建一个距离数组dist,存储源点到每个顶点的最短距离。
初始时,源点到自身的距离为0,其他顶点的距离为无穷大。
2. 将源点插入到优先队列中。
堆的原理和应用1. 堆的定义和特点堆(Heap)是一种特殊的数据结构,它是一种完全二叉树,并且满足堆特性:对于最大堆,父节点的值大于或等于子节点的值;对于最小堆,父节点的值小于或等于子节点的值。
堆最常见的应用就是优先队列,能够高效地找到最大或最小元素。
堆具有以下特点: - 堆是一棵完全二叉树,节点顺序从上到下、从左到右; - 最大堆(或最小堆)的父节点的值大于等于(或小于等于)子节点的值; - 堆的根节点是整个堆中最大(或最小)的元素。
2. 堆的实现和操作堆可以使用数组来实现,通过满足以下规则: - 对于节点i,其左子节点的索引是2i+1,右子节点的索引是2i+2; - 对于节点i,其父节点的索引是(i-1)/2。
常用的堆操作包括插入元素、删除堆顶元素、堆元素的上浮和下沉。
•插入元素:将元素插入到堆的尾部,然后依次与父节点进行比较,若满足堆特性,则停止比较;否则继续交换位置。
•删除堆顶元素:将堆的尾部元素替换到堆顶,然后依次与子节点进行比较,交换位置直到满足堆特性。
•堆元素的上浮:将该元素与父节点进行比较,若满足堆特性,则停止比较;否则继续交换位置。
•堆元素的下沉:将该元素与子节点进行比较,交换位置直到满足堆特性。
3. 优先队列的实现优先队列是堆的一种常见应用,它能够高效地找到最大(或最小)元素。
优先队列可以支持插入操作和获取最大(或最小)元素操作。
使用堆实现优先队列的步骤如下: 1. 创建一个空的堆作为优先队列。
2. 将元素依次插入到堆中。
3. 获取堆顶元素并删除。
4. 执行上述操作,直到堆为空。
优先队列的应用非常广泛,例如任务调度、数据压缩、图像处理等领域。
4. 堆排序算法堆排序是一种基于堆的排序算法,它可以在O(nlogn)的时间复杂度下完成排序操作。
堆排序的基本思想是: 1. 将待排序的序列构建成一个最大堆。
2. 此时,整个序列的最大值就是堆顶的根节点。
3. 将根节点与最后一个节点交换,然后对前面n-1个节点进行堆调整。
c++优先队列实现原理
C++的优先队列是通过堆(heap)实现的。
堆是一种特殊的二
叉树结构,它满足以下两个条件:
1. 完全二叉树:除最后一层外,每一层都是满的,并且最后一层的节点都尽量靠左排列。
2. 堆序性:对于每个节点X,X的父节点的值(如果存在)必须大于或等于X的值。
C++的优先队列会根据元素的优先级自动进行排序,并且每次
取出最高优先级的元素。
它使用一个二叉堆(通常是最大堆)来实现。
在C++的STL库中,优先队列的实现是通过
std::priority_queue模板类来实现的。
这个类内部使用一个std::vector容器来存储元素,并且使用一个比较函数(默认是std::less)来确定元素的优先级。
当元素插入到优先队列中时,它会根据比较函数的规则将元素插入到正确的位置,以保证最高优先级的元素在队列的最前面。
当从优先队列中取出元素时,它会取出队列的第一个元素,并将其移出队列。
然后,它会重新调整剩余元素的顺序,以确保下一个元素仍然是最高优先级的元素。
总的来说,C++的优先队列使用二叉堆来存储和维护元素的顺序,并且根据比较函数来确定元素的优先级。
这使得插入和删
除操作的时间复杂度都是O(logN),其中N是队列中元素的个数。
C++中的优先队列是一种基于堆的数据结构,它能够高效地处理优先级较高的元素,常常用于Dijkstra 算法等场景。
本文将介绍C++优先队列的定义、使用方法以及注意事项等方面的内容。
一、定义C++中的优先队列通过标准库queue头文件中的priority_queue类实现。
其定义形式如下:priority_queue <T, Container, Compare> q;其中,T为队列元素的类型;Container为底层容器类型,默认为vector;Compare为元素优先级比较的仿函数类型,默认为less<T>(即按照元素值从大到小排序)。
二、插入元素使用优先队列插入元素可以通过push()方法实现,如下所示:q.push(element);其中,element为待插入的元素值。
三、访问元素使用优先队列访问头部元素(即优先级最高的元素)可以通过top()方法实现,如下所示:q.top();四、删除元素使用优先队列删除头部元素(即优先级最高的元素)可以通过pop()方法实现,如下所示:q.pop();五、注意事项1. 优先队列中存储的元素应当支持比较运算符(<、>等),以便进行元素优先级的比较。
2. 优先队列的底层实现采用的是堆,因此在插入、删除元素时时间复杂度为O(logN),其中N为元素个数。
3. 优先队列无法修改已经插入的元素值,因此如果需要修改元素值,需先从队列中删除这个元素,然后再将修改后的元素重新插入队列。
4. 自定义优先级比较函数时应当确保函数具有严格的弱序性,即对于任意两个元素a、b,满足a<b和b<a至少一种情况成立。
本文向读者介绍了C++中优先队列的定义、使用方法以及注意事项等方面的内容,希望读者能够在实际编码过程中灵活地运用这一数据结构,提高程序的效率。
沈阳航空航天大学数据结构课程设计报告题目:应用堆实现一个优先队列院(系):理学院专业:信息与计算科学班级:学号:姓名:指导教师:2011年12月沈阳航空航天大学课程设计报告目录1题目介绍和功能要求 (1)1.1优先队列(PRIORITY QUEUE) (1)1.2基本功能 (1)1.3功能要求 (1)2 系统功能模块结构图 (2)2.1系统功能结构框图 (2)2.2系统主要模块的功能说明 (2)3 使用的数据结构的描述 (3)3.1数据结构设计 (3)3.2数据结构用法说明 (3)4 函数的描述 (5)5 算法流程图 (7)5.1H EAP A DJUST函数 (7)5.2C REATE H EAP 函数 (8)5.3P RINT 函数 (8)5.3I NSERT函数 (9)5.4M INIMUN函数 (9)5.5E XTRACT_M IN 函数 (10)6 测试/运行的结果 (11)参考文献 (15)附录 (17)1题目介绍和功能要求1.1优先队列(priority queue)是不同于先进先出队列的另一种队列。
每次从队列中取出的是具有最高优先权的元素,它可以用于很多场合的数据结构。
1.2 基本功能1 Insert(S,x)将元素x插入到集合S(本题为数组A),并且把A调整为小头椎。
2 Minimum(S0返回S中的最小元素,并且将A调整为小顶椎。
3 Extract_Min(S)删除S中的最小关键字1.3 功能要求可设计要求以堆作为辅助结构实现一个优先队列。
要将堆结构嵌入到队列结构中,以作为其数据组织的以部分。
此处由于要用堆实现队列,所以堆结构的储存表示要求用数组。
要求:1. 设计并实现优先队列的数据结构,包括其上的基本操作;2. 以堆结构为辅助结构实现优先队列的储存表示并实现其上的基本操作;3. 实现优先队列的出队、入队操作;4. 给出动态演示过程(选作);2 系统功能模块结构图2.1 系统功能结构框图图2.1系统的模块图2.2 系统主要模块的功能说明1.插入功能模块:Insert(A,x) 将元素x插入到数组A,并且把A调整为小头椎。
2. 删除功能模块:Extract_Min(A),删除数组A中的最小关键字,并且将A调整为小顶椎。
3. 输出功能模块:Print(A)把集合S中的元素按小头堆输出。
4. 创建队列功能模块:CreateHeap(A) 对于数组A中元素创建小头椎。
5. 返回最小优先级功能模块:Minimun(A) 返回集合A中优先级最小的堆3 使用的数据结构的描述3.1 数据结构设计优先队列是不同于先进先出队列的另一种队列。
每次从队列中取出的是具有最高优先权的元素,按照题意可知,建立了小顶堆,元素越小优先级越高。
堆的定义:若含n 个元素的序列 {k1,k2 ,…,kn } ,满足下列关系时称作"小顶堆" 或"大顶" 。
"堆顶" 元素为序列中的"最小值"或"最大值"。
堆举例:{12,36,24,85,47,30,53,91}图3.1 小顶堆可将堆序列看成完全二叉树,则堆顶元素(完全二叉树的根)必为序列中 n 个元素的最小值或最大值 结合题目要求3.2 数据结构用法说明从无序序列的第⎣n/2⎦个元素(即此无序序列对应的完全二叉树的最后一个非终端结点)起,至第一个元素止,进行反复筛选)1,2,...n/2(i k k k k 12i i 2ii =⎩⎨⎧<=<=+例如:无序序列建成一个小顶堆{49,38,65,97,76,13,27,49}图3.2 小顶堆调整a 图3.3 小顶堆调整b图3.4 小顶堆调整c 图3.5 小顶堆调整d图3.6 小顶堆调整e4 函数的描述主要函数设计:(1) void Print(int *a,int t)作用:输出优先队列参数表:a 为存储优先队列的数组。
t 为参数,为0是直接输出优先队列;否则对要变换元素进行标记。
如数字6:为与3和7比较。
图4.1例图 (2)void CreateHeap(int *a)作用:对于数组a 进行调整为有小顶堆。
参数表:a 为存储优先队列的数组。
算法思想:从无序序列的第⎣n/2⎦个元素(即此无序序列对应的完全二叉树的最后一个非终端结点)起,至第一个元素止,进行反复筛选,用递归方法调用HeapAdjust ();(3)HeapAdjust(int *a,int s,int m)作用:为小顶堆。
为小顶堆调整后]....[]...1[m s a m s a + 参数表:a 为存储优先队列的数组。
s 为要调整的起始位置。
m 为要调整的末端位置。
算法思想:通过 i 个要满足且(i=s ,2s ,2s+1,3s …m/2)(4)void Insert(int *a,int x)作用:将x 插入到优先队列a 中并把a 调整为小顶堆。
参数表:x 要插入的元素a 为存储优先队列的数组。
{s,...m/2)(i k k k k 12i i 2i i =<=<=+且算法思想:先将x插入到a的最后位置,然后判断a(k/2)a(k) 是否成立,成立则a(k/2)a(k)与互换,否则退出函数。
(5)int Minimun(int *a)作用:返回优先队列中优先级最高的元素(这为最小元素)。
参数表:a 为存储优先队列的数组。
算法思想:由于用的是小顶堆,所以直接返回堆顶就行了。
(6) int Extract_Min(int *a)作用:从优先队列中删除优先级最高的元素(这为最小元素),并重新调整为小顶堆。
参数表:a 为存储优先队列的数组。
算法思想:由于用的是小顶堆,所以直接返回堆顶,并删除堆顶,然后将堆的最后一个元素放到堆顶,在调用 HeapAdjust(int*a,int 1,int m)就行了。
5 算法流程图5.1 HeapAdjust函数图5.1 HeapAdjust流程图5.2 CreateHeap 函数图5.2 CreateHeap 的流程图5.3 Print 函数图5.3 Print 函数的流程图5.3 Insert函数图5.4 Insert函数流程图5.4 Minimun函数图 5.5 Minimun函数流程图5.5 Extract_Min 函数图 5.6 Extract_Min 函数流程图6 测试/运行的结果例如:输入{49,38,65,97,76,13,27,49}如下:图 6.1 输入格式图初始堆为:图 6.2 初始堆调整小顶堆过程为:图6.3 调整图调整后的小顶堆为:图 6.4 调整后小顶堆图主函数功能操作如下:图 6.5 主函数功能操作图插入时选择功能1其输入如下:图 6.6插入操作图插入过程如下:图 6.7 插入过程图返回最小值,选择功能4,结果如下:图 6.8返回最小值删除时选择功能2其过程如下:图 6.9删除过程删除后结果如下:图 6.10删除后结果参考文献[1] 谭浩强著. C程序设计(第三版). 北京: 清华大学出版社,2005[2] 数据结构: C语言版/严蔚敏,吴伟明编著.—北京:清华大学出版社,2007[3]汪杰. 数据结构经典算法实现[M]. 北京:人民邮电出版社,2004[4]李春葆. 数据结构解析(C语言版)[M]. 北京:清华大学出版社,2002附录#include "stdafx.h"#include "stdio.h"#include <math.h>#include<windows.h>#include<string.h>#include "stdlib.h "#include<time.h>#define MAX 100#define INF 0.00001void Print(int *a,int t){int i,j,k,n,m;m=int(log(a[0])/log(2)+INF)+1;n=int(pow(2,m))-1;for(i=1;i<=m;i++){for(k=int(pow(2,(i-1)));k<=int(pow(2,i))-1;k++){if(k==a[0]+1) break;for(j=1;j<=n/2;j++)printf(" ");if(k==t)printf("<%d>",a[k]);else printf("%d",a[k]);for(j=1;j<=n/2+1;j++)printf(" ");}printf("\n");n=n/2;}}void HeapAdjust(int *a,int s,int m) //a[s+1...m]为小顶堆,调整后a[s...m]为小顶堆{int j,ac=a[s];for(j=2*s;j<=m;j*=2){getchar();Print(a,j/2);if(j<m && a[j]>a[j+1]) j++;if(ac<a[j]) break;a[s]=a[j];s=j;a[s]=ac;}}void CreateHeap(int *a){int i,n;printf("请输入要创建的个数 ");scanf("%d",&n);a[0]=n;printf("请输入的数字\n");for(i=1;i<=n;i++)scanf("%d",&a[i]);printf("当前堆为:\n");Print(a,0);getchar();printf("现在对其进行调整:\n");for(i=a[0]/2;i>0;i--)HeapAdjust(a,i,a[0]);getchar();printf("调整后的为:\n");Print(a,0);getchar();}void Insert(int *a,int x){int i,n=a[0];a[n+1]=x;a[0]++;getchar();Print(a,a[0]);for(i=a[0];i>1;){if(a[i]<a[i/2]){getchar();a[i]=a[i/2];i=i/2;a[i]=x;Print(a,i);}else break;}}int Minimun(int *a){return a[1];}int Extract_Min(int *a){printf("原来的是:\n");Print(a,0);Sleep(2000);int n,ma=a[1];n=a[0];a[1]=a[n];a[0]--;HeapAdjust(a,1,n-1);getchar();printf("删除后的是:\n");Print(a,0);return ma;}void menu(){system( "cls ");printf("\t\t\t************************\n");printf("\t\t\t* 请选择功能 *\n");printf("\t\t\t*1:插入(入队): *\n");printf("\t\t\t*2:删除(出队): *\n");printf("\t\t\t*3:输出: *\n");printf("\t\t\t*4:返回最小值: *\n");printf("\t\t\t*0:退出: *\n");printf("\t\t\t************************\n"); }void main(){int x,a[MAX+1],gong;a[0]=0;CreateHeap(a);menu();scanf("%d",&gong);while(gong){switch(gong){case 1:printf("请输入插入数值\n");scanf("%d",&x);Insert(a,x);break;case 2:x=Extract_Min(a);printf("删除的元素:%d\n",x);break;case 3:Print(a,0);break;case 4:x=Minimun(a);printf("最小值为: %d\n",x);case 0: break;default :m enu();break;}scanf("%d",&gong);}沈阳航空航天大学课程设计报告。