面试题9:数组堆化、堆的插入、堆的删除、堆排序

参考:白话经典算法系列之七 堆与堆排序

 1 #include <iostream>
 2 #include <climits>
 3 #include <vector>
 4 using namespace std;
 5
 6 namespace heap {
 7
 8 //insert an element to a heap
 9 void insertToHeap(vector<int>& h, int x) {
10     h.push_back(x);
11     int n = h.size();
12
13     int i = n - 1;
14     int p = (i - 1) / 2;  //parent
15     int temp = x;
16     while (p >= 0 && i != 0) {
17         if (h[p] <= temp) {
18             break;
19         }
20         h[i] = h[p];
21         i = p;
22         p = (i - 1) / 2;
23     }
24     h[i] = temp;
25 }
26
27 void minHeapFixdown(vector<int>& h, int i, int n) {
28     int tmp = h[i];
29     int j = 2 * i + 1;
30     while (j < n) {
31         if (j + 1 < n && h[j + 1] < h[j]) {
32             j++;
33         }
34         if (h[j] >= tmp) {
35             break;
36         }
37         h[i] = h[j];
38         i = j;
39         j = 2 * i + 1;
40     }
41     h[i] = tmp;
42 }
43
44 //delete an element from a heap
45 void deleteFromHeap(vector<int>& h) {
46     if (h.empty())
47         return;
48     if (h.size() == 1) {
49         h.clear();
50         return;
51     }
52     int n = h.size();
53     h[0] = h[n - 1];
54     h.erase(h.end() - 1);
55     minHeapFixdown(h, 0, n);
56 }
57
58 //make an array Minimum heap
59 void heapArray(vector<int>& h) {
60     int n = h.size();
61     for (int i = n / 2 - 1; i >= 0; i--) {
62         minHeapFixdown(h, i, n);
63     }
64 }
65
66 void heapSort(vector<int>& h) {
67     int n = h.size();
68     vector<int> tmp = h;
69     for (int i = 0; i < n; i++) {
70         h[i] = tmp[0];
71         deleteFromHeap(tmp);
72     }
73 }
74
75 void printHeap(vector<int>& testVec) {
76     for (size_t i = 0; i < testVec.size(); i++) {
77         std::cout << testVec[i] << ",";
78     }
79     std::cout << std::endl;
80 }
81 }
82 ;
83
84 int main() {
85     vector<int> testVec = { 0, 3, 9, 1, 3, 5 };
86     heap::heapArray(testVec);
87     heap::printHeap(testVec);
88
89     heap::deleteFromHeap(testVec);
90     heap::printHeap(testVec);
91
92     heap::insertToHeap(testVec, 4);
93     heap::printHeap(testVec);
94
95     heap::heapSort(testVec);
96     heap::printHeap(testVec);
97
98     return 0;
99 }
时间: 2024-08-06 07:35:36

面试题9:数组堆化、堆的插入、堆的删除、堆排序的相关文章

数组堆化

今天学习了数组堆化, 堆化启发我们的思维, 百尺竿头更进一步! 理解堆化 说是堆化, 其实就是利用树的性质表示在数组中, 利用下标和书上左右孩子对应关系. 公式 左孩子下标 = 根下标 * 2 + 1 右孩子下标 = 根下标 * 2 + 2 递归 递归 fixHead 函数来解决满足大顶堆或者小顶堆的问题, 说到递归, 我们一般会说递归结束条件, 数组越界或者已经符合条件, 结束递归. 源码 public class Main { public static void main(String[]

深拷贝和数组扁平化

这两天做笔试题的时候遇到了深拷贝,在js中,一些基本类型是存在栈空间里的,而引用类型如object function之类的都是存在堆内存之中,只不过是他们的地址是在栈内存,通过地址找到对内存空间中的数据 上代码 function deepClone(obj){ var cloneobj = Array.isArray(obj)?[]:{}; //判断是数组还是对象 if(obj && typeof obj === "object"){ //判断当前的对象是否存在且类型是

进程默认堆和额外创建的堆

在<Windows核心编程>第五版的第十八章 <堆> 中提到了进程默认堆和额外创建的堆.这在编程中是十分重要的知识,今天整理一下. 1,堆非常适合分配大量的小型数据.使用堆可以让程序员专心解决手头的问题,而不必理会分配粒度和页面边界之类的事情.因此堆是管理链表和数的最佳方式.但是堆进行内存分配和释放时的速度比其他方式都慢,而且无法对物理存储器的调拨和撤销调拨进行控制. 为了能适应各种硬件平台,如果程序员想要控制物理存储器的调拨和撤销调拨,就不应该使用堆,而应该使用虚拟内存(Virt

数据结构——堆(Heap)大根堆、小根堆

Heap是一种数据结构具有以下的特点: 1)完全二叉树: 2)heap中存储的值是偏序: Min-heap: 父节点的值小于或等于子节点的值: Max-heap: 父节点的值大于或等于子节点的值: 堆的存储: 一般都用数组来表示堆,i结点的父结点下标就为(i–1)/2.它的左右子结点下标分别为2 * i + 1和2 * i + 2.如第0个结点左右子结点下标分别为1和2. 堆的操作:insert 插入一个元素:新元素被加入到heap的末尾,然后更新树以恢复堆的次序. 每次插入都是将新数据放在数组

Java堆内存Heap与非堆内存Non-Heap

堆(Heap)和非堆(Non-heap)内存 按照官方的说法:"Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配.堆是在 Java 虚拟机启动时创建的.""在JVM中堆之外的内存称为非堆内存(Non-heap memory)".可以看出JVM主要管理两种类型的内存:堆和非堆.简单来说堆就是Java代码可及的内存,是留给开发人员使用的:非堆就是JVM留给 自己用的,所以方法区.JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)

排序 堆的实现和利用堆来排序

*/--> pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;} pre.src {background-color: Black; color: White;}

华为历年试题(数组8)

有一个数组a[N]如a[10]={0,1,2,3,4,5,6,7,8,9} 每隔两个数删除一个数,如0,1,2(删除),3,4,5(删除),6,7,8(删除),9, 到数组尾部回到数组头部继续删除,要求编写一个函数实现实现上述操作, 返回最后一个数的数组下标. 函数接口:int getLast(int iLen) 参数:数组初始元素个数iLen #include<iostream> using namespace std; struct LinkP{ int val; LinkP *next;

[硕.Love Python] FibonacciHeap(F堆 & 斐波那契堆)

class Node(object):     __slots__ = [         'data', 'child', 'left', 'right',         'degree', 'parent', 'childCut',     ]     def __init__(self, data):         self.data = data         self.child = None         self.left = None         self.right

2016 Multi-University Training Contest 5 1012 World is Exploding 树状数组+离线化

1012 World is Exploding 题意:选四个数,满足a<b and A[a]<A[b]   c<d and A[c]>A[d] 问有几个这样的集合 思路: 树状数组+离线化 先处理出每个数左边比它小 大,右边比它大 小的数目,用cnt[][i]表示.最后统计一下减去重复的就可以 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <

经典面试题 之 数组的循环右移

经典面试题 之 数组的循环右移 题目的大意是将一个长度为n的数组A内的元素循环右移m位(当然左移也可以),比如数组 {1, 2, 3, 4, 5}右移3位之后就变成{3, 4, 5, 1, 2}. 这题最平凡的做法是开另一个大小一样的数组B,遍历一下,令B[(i + m) % n] = A[i],再将B的内容写回到A即可.这个方法的时间复杂度为O(N),空间复杂度也为O(N). 很明显,需要优化空间的使用.有一种很优美但不太好懂的方法,是先将A的元素倒置,即{1, 2, 3, 4, 5}变成{5