108次练习之堆的声明及实现(二)

  昨天写完堆的代码后,今天又敲了一下,顺便用到了函数对象,可以指定生成最小/大堆.

  (注释就懒得写了,有什么问题可以私下留言,或者看我上篇文章,毕竟本文仅供个人娱乐)

/*
*文件说明:堆的相关声明及实现(第二遍)
*作者:高小调
*日期:2016-12-27
*集成开发环境:Microsoft Visual Studio 2010
*/
#include<vector>
template<typename T>
struct Min{
	bool operator()(T left,T right){
		return left<right;
	}
};
template<typename T>
struct Max{
	bool operator()(T left,T right){
		return left>right;
	}
};

template<typename T,typename class Type = Min<T>>
class Heap{
public:
	Heap(){}
	Heap(T arr[],size_t sz)
		:_a(arr,arr+sz){
		size_t LastNotLeapNode = (_a.size()-2)/2;
		for(int idx=LastNotLeapNode; idx>=0; --idx){
			_AdjustDown(idx);
		}
	}

	void Push(const T &e){
		_a.push_back(e);
		size_t LastNotLeapNode = (_a.size()-2)/2;
		_AdjustUp(LastNotLeapNode);
	}

	void Pop(){
		swap(_a[0],_a[_a.size()-1]);
		_a.pop_back();
		_AdjustDown(0);
	}
protected:

	void _AdjustDown(size_t idx){
		size_t parent = idx;
		size_t child = idx*2+1;
		while(child<_a.size()){

			if(child+1<_a.size() && Type()(_a[child+1],_a[child])){
				++child;
			}

			if(Type()(_a[child],_a[parent])){
				swap(_a[child],_a[parent]);
				parent = child;
				child = parent*2+1;
			}else{
				break;
			}

		}
	}

	void _AdjustUp(size_t idx){
		size_t parent = idx;
		size_t child = 2*idx+1;
		while(child<_a.size() && child>parent){

			if(child+1<_a.size() && Type()(_a[child+1] , _a[child])){
				++child;
			}

			if(Type()(_a[child],_a[parent])){
				swap(_a[child],_a[parent]);
				child = parent;
				parent = (child-1)/2;
			}else{
				break;
			}

		}
	}

private:
	vector<T> _a;
};
/*
*文件说明:测试文件
*作者:高小调
*日期:2016-12-26
*集成开发环境:Microsoft Visual Studio 2010
*/
#include<iostream>
using namespace std;
#include"Heap2.h"
void TestHeap(){
	int arr[] = {10,16,18,12,11,13,15,17,14,19};
	size_t sz = sizeof(arr)/sizeof(arr[0]);
	Heap<int> h1(arr,sz);			//小堆
	Heap<int,Max<int>> h2(arr,sz);	//大堆
	h1.Pop();
	h1.Push(5);
	h2.Pop();
	h2.Push(20);
}
int main(){
	TestHeap();
	return 0;
}

  总结:

  第二遍再去敲堆的时候,就行云流水多了,但还是犯了个小错误:在构造函数中,没有给_a初始化...

  最基础的,就是最精华的!

  继续努力!

时间: 2024-11-05 12:33:19

108次练习之堆的声明及实现(二)的相关文章

c++ 依据输入动态声明数组(一维,二维)

较早的编译器是不同意这样做的,所以一些书籍比方以Tc解说的书本都说数组的下标不能是变量.在vc6.0下亦是如此. 只是在一些较新的编译器如dev c++已经支持了,例如以下代码不会报错 #include <stdio.h> #include <stdlib.h> int main() { int a; int i; scanf("%d",&a); int c[a]; for( i =0 ;i<a;i++) scanf("%d",

C++ 在堆上开辟与释放二维、三维指针

//C++ 在堆上开辟与释放二维.三维指针 #include<iostream> using namespace std; int main() { //二级指针的开辟与释放 int number = 0; int** p = new int*[4]; for(int i = 0; i < 4; i++) //分级定义数组大小 { p[i] = new int[4]; } for(int i = 0; i < 4; i++) { for(int j = 0; j < 4; j

堆排序:什么是堆?什么是最大堆?二叉堆是什么?堆排序算法是怎么样的?PHP如何实现堆排序?

本文标签:  堆排序 php php算法 堆排序算法 二叉堆 数据结构 REST   服务器 什么是堆 这里的堆(二叉堆),指得不是堆栈的那个堆,而是一种数据结构. 堆可以视为一棵完全的二叉树,完全二叉树的一个"优秀"的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素. 数组与堆之间的关系 二叉堆一般分为两种:最大堆和最小堆. 什么是最大堆 堆中每个父节点的元素值都大于等于其孩子结点(如果存在),这样的堆就是一个最大堆 因此,最大堆中的

STL源码笔记(15)—堆和优先级队列(二)

STL源码笔记(15)-堆和优先级队列 优先级队列的源码实现基于heap的操作,底层容器默认是vector. 优先级队列简介 优先级队列跟队列类似,一端插入一端删除,不同的是,优先级队列的元素入队后会根据其优先级进行调整,默认情况下优先级高的将优先出队,在SGI STL中,优先级队列的功能保证由heap实现:stl_heap.h中,heap的分析见:STL堆源码分析 优先级队列构造函数 默认情况下,优先级队列使用vector作为底层容器,使用less作为比较函数,其在源码中的定义声明如下: te

堆(Heap)和二叉堆(Binary heap)

堆(Heap): The operations commonly performed with a heap are: create-heap: create an empty heap heapify: create a heap out of given array of elements find-max or find-min: find the maximum item of a max-heap or a minimum item of a min-heap (aka, peek)

[leetcode]108. Convert Sorted Array to Binary Search Tree构建二叉搜索树

构建二叉搜索树 /* 利用二叉搜索树的特点:根节点是中间的数 每次找到中间数,左右子树递归子数组 */ public TreeNode sortedArrayToBST(int[] nums) { return builder(nums,0,nums.length-1); } public TreeNode builder(int[] nums,int left,int right) { if (left>right) return null; int mid = (left+right)/2;

JAVA基础-栈与堆,static、final修饰符、内部类和Java内存分配

Java栈与堆 堆:顺序随意 栈:后进先出(Last-in/First-Out). Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.anewarray和multianewarray等指令建立,它们不需要程序代码来显式的释放.堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据.但缺点是,由于要在运行时动态分配内存,存取速度较慢. 栈的优势是

数据结构 之 二叉堆(Heap)

注:本节主要讨论最大堆(最小堆同理). 一.堆的概念 堆,又称二叉堆.同二叉查找树一样,堆也有两个性质,即结构性和堆序性. 1.结构性质: 堆是一棵被全然填满的二叉树.有可能的例外是在底层.底层上的元素从左到右填入.这种树称为全然二叉树(complete binary tree).下图就是这样一个样例. 对于全然二叉树,有这样一些性质: (1).一棵高h的全然二叉树,其包括2^h ~ (2^(h+1) - 1)个节点.也就是说.全然二叉树的高是[logN],显然它是O(logN). (2).全然

优先队列(堆)的7种操作

1.优先队列有两项基本操作:插入(insert)和删除最小项(deleteMin),后者的工作是找出.返回和删除优先队列中最小的元素.而insert操作则等价于enqueue(入队),deleteMin则等价于dequeue(出队).补充:C++提供2个版本的deleteMin,一个删除最小项,另一个在删除最小项的同时在通过引用传递的对象中存储所删除的值. 2.优先队列的类接口 template <typename Comparable> class BinaryHeap { public: