用数组实现的最大堆(C++)

 1 #include <iostream>
 2 #include <assert.h>
 3
 4 using namespace std;
 5 void swap(int* a,int pos,int j){
 6     int temp=a[pos];
 7     a[pos]=a[j];
 8     a[j]=temp;
 9 }
10 class heap{
11 private:
12     int* Heap;
13     int maxsize;  //堆的大小
14     int n;        //当前堆中的元素个数
15
16     //把一个元素移动到合适的位置
17     void shiftdown(int pos){
18       while(!isLeaf(pos)){     //如果是叶子结点就停止
19         int j=leftchild(pos);
20         int rc=rightchild(pos);
21         if((rc<n)&&Heap[rc]>Heap[j])
22             j=rc;               //把j设置为最大孩子的下标
23         if(Heap[pos]>Heap[j])
24             return;           //当前结点数值比两个孩子最大值还大就结束了
25         swap(Heap,pos,j);
26         pos=j;
27       }
28     }
29
30 public:
31     heap(int* h,int num,int maxi){  //构造函数
32         Heap=h;
33         n=num;
34         maxsize=maxi;
35         buildHeap();
36     }
37     int size()const{         //返回当前个数
38         return n;
39     }
40     bool isLeaf(int pos) const{  //判断是否是叶子
41         return (pos>=n/2)&&(pos<n);
42     }
43     int leftchild(int pos) const{  //返回结点左孩子
44         return 2*pos+1;
45     }
46     int rightchild(int pos) const{  //返回结点右孩子
47         return 2*pos+2;
48     }
49     int parent(int pos) const{       //返回父亲结点
50         return (pos-1)/2;
51     }
52     void buildHeap(){            //把堆进行堆化
53         for(int i=n/2-1;i>=0;i--)
54             shiftdown(i);
55     }
56     //把一个元素插入堆
57     void insert(const int& it){
58         assert(n<maxsize);
59         int curr=n++;
60         Heap[curr]=it;  //把元素插入到堆的最后
61         //把这个元素向上移动
62         while((curr!=0)&&(Heap[curr]>Heap[parent(curr)])){
63             swap(Heap,curr,parent(curr));
64             curr=parent(curr);
65         }
66     }
67     int remove(int pos){     //移除一个结点
68         assert((pos>=0)&&(pos<n));
69         if(pos==(n-1))  //如果是最后一个元素
70             n--;
71         else{
72             swap(Heap,pos,--n);
73             while((pos!=0)&&(Heap[pos]>Heap[parent(pos)])){
74                 swap(Heap,pos,parent(pos));
75                 pos=parent(pos);
76             }
77             if(n!=0)
78                 shiftdown(pos);
79         }
80         return Heap[n];
81     }
82 };
时间: 2024-08-11 23:39:15

用数组实现的最大堆(C++)的相关文章

数据结构c++语言描述&mdash;&mdash;最大堆(MaxHeap)

一.最大堆的插入 图9-3a 给出了一个具有5个元素的最大堆.由于堆是完全二叉树,当加入一个元素形成6元素堆时,其结构必如9-3b 所示.如果插入元素的值为1,则插入后该元素成为2的左孩子,相反,若新元素的值为5,则该元素不能成为2的左孩子(否则将改变最大树的特性),应把2下移为左孩子(如图9 - 3 c所示),同时还得决定在最大堆中5是否占据2原来的位置.由于父元素20大于等于新插入的元素5,因此可以在原2所在位置插入新的元素.假设新元素的值为21而不是5,这时,同图9-3c 一样,把2下移为

最大堆的简单实现

img {border: 1.5px solid black } 二叉堆是一棵完全二叉树,完全二叉树:对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树. 可以理解为将数据按照"层序遍历"的方式排列到二叉树的每一个节点,完全二叉树不一定是满二叉树,完全二叉树缺少的部分在树的右下方. 如果堆中某个节点的值总是不大于其父节点的值,那么这种堆就是最大堆. 由于最大堆的元素是按照一层一层的顺序排列的,所以我们可以使用数组

阿布学排序之堆排序

/** * 需求:堆排序的实现 * 知识储备: * 满二叉树:除叶子结点外的所有结点均有两个子结点,所有叶子结点必须在同一层上. * 完全二叉树: * 若二叉树的深度为h,除第h层外,其它各层(1~h-1)的节点数都达到最大个数,第h层所有结点都连续集中在最左边. * 完全二叉树是有满二叉树而引出来的,对于深度为K的,有N个结点的二叉树,当且仅当每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称它为完全二叉树. * * 二叉堆是完全二叉树或者是近似完全二叉树. * 二叉堆特性: *

堆排序(选择排序)-八大排序三大查找汇总(2)

二叉堆的定义 二叉堆是完全二叉树或者是近似完全二叉树. 二叉堆满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值. 2.每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆). 当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆.当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆.下图展示一个最小堆: 堆的存储 一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2.它的左右子结点下标分别为2 * i + 1和2 * i + 2.如

算法1(摘录)

第三章 算法 前言:许多人对算法的看法是截然不同的,我之前提到过了.不过,我要说的还是那句话:算法体现编程思想,编程思想指引算法. 同时,有许多人认为简单算法都太简单了,应当去学习一些更为实用的复杂算法.不过,许多复杂算法都是从简单算法演绎而来的,这里就不一一举例了.而且,算法千千万万.更为重要的是从算法中体会编程的思想. 4.1 简单问题算法 PS:接下来是一些入门问题,简单到都没有具体算法可言.但这些问题是我们当初对算法的入门.如果不喜欢,可以跳过. 实例111 任意次方后的最后三位 问题:

优先队列及其基本操作的堆实现

用代码说话 /* 本代码实现优先队列:分为最大优秀队列和最小优先队列 优先队列用于维护一组元素构成的集合S的数据结构,其中的 每一个元素都有一个相关的值,称为关键字. 一个最大优先队列支持以下操作: insert(S,x)向S中插入元素x; maximum(S)返回S中的最大键值元素; extract-max(S)去掉并且返回S中的最大键值元素; increase-key(S,x,k)将元素x的关键字增加到k,假设k要不小于x的原关键字 一个最小优先队列支持以下操作: insert(S,x)向S

排序算法系列——堆排序

记录学习点滴,菜鸟成长记 堆排序引入了另一种算法设计技巧:使用一种我们称之为“堆”的数据结构来进行数据管理. 堆排序算是真正意义上的利用数据结构来求解数组排序的方法. “插入排序”和“归并排序”可以看做是一种“计算机体力活”,体现的思想更多的是去模拟最简单的人类思维,比如插入排序过程中的比较,归并中子问题合并时的比较. “堆排序”可以看做是“计算机脑力活”,他利用了一种结构化的语言来表达,这种结构化带来一些性质,比如左右孩子.比[堆大小的一半向下取整]大的下标都是叶节点不需要维护其最大堆性质等.

排序问题1

h2.western { font-family: "Liberation Sans", sans-serif; font-size: 16pt } h2.cjk { font-size: 16pt } h2.ctl { font-size: 16pt } h1 { margin-bottom: 0.21cm } h1.western { font-family: "Liberation Sans", sans-serif; font-size: 18pt } h1

自己整理的算法 (6)堆排序

package sort; //最大堆的特性是,某个节点的值最多和其父节点的值一样大.这样,堆中的最大元素存放在根节点中 //:并且,在以某一个节点为根的子树中,各节点的值都不大于该子树根节点的值 public class HeapSort { public static void heapSort(int[] list) { if (list == null || list.length <= 1) { return; } //构建最大堆 //相当于add的作用,此方法结束后,就构建好了有序的