`
chentingk
  • 浏览: 20263 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

教你玩转min_heap && 指针queue

 
阅读更多


 一
.Min_heap的建立

   堆是一种数据结构,分为最大值堆和最小值堆;

   堆的内部结构是一个完全二叉树;

   最大值堆的根节点是树中最大的元素,而父节点比任意一个子节点都要大;

   最小值堆的根节点是树中最小的元素,父节点比任意一个子节点都要小;

   我们用以下数组为建堆的材料:int testH[]={24,63,23,47,232,46,12,57,24,74};

   逻辑中,我们对数组的结构可以这样设计:

 

 

-----图有点错了,最后两个是8和9

  我们要建立一个堆,最重要的是三点:初始化堆,堆内调整算法,插入/删除;

设节点的下标为i(i!=0),孩子为2*i,2*i+1.

如果heap[i]>min(heap[2*i],heap[2*i+1])则交换节点,然后调整比如heap[2*i]与其孩子heap[2*2*i],heap[2*2*i+1].

节点规则:heap[i]<heap[2*i],heap[i]<heap[2*i+1];

 

(1)初始化堆我们的思想是从一个最小单元开始排序,就是最后一个父节点开始向前排序,而父节点的父节点是重叠子问题,只要最后一个父节点是最优的结构,往上解最优的时候就会获得全局最优的解集。

(2)当我们调整一个节点的时候,我们只需要往那个交换的节点的子节点进行调整。最小堆的一个规则,最简单的结构到复杂的结构的特点都是唯一的,也就是父节点比任意一个子节点都小。例如

 

 

我们要调整55这个节点,44,和46已经调整好了(从后往前调整),55>46>44,则交换55和44这两个节点。这是不必调整46和它的子节点,理由很简单,它是个稳定的结构,没有进行节点调整,所以程序不必理会,而交换的44节点的结构变换了,要向下调整。所以建堆的思路是:从父节点往前调整,每一次调整深度优先。

 

初始化算法:

//初始化
void inith(int *a)
{
	for(int i=0;i<hlength;i++)
	{
		heap[i]=*(a+i);
	}
	cout<<endl;
}
//建立堆
void build()
{
	for(int i=hlength/2;i>=0;i--)
	{
		down(i);

	}
}
//从上往下调整法
void down(int p)
{
	int q=p*2;
	int a=heap[p];

	while(q<hlength)
	{
		if(q<hlength && heap[q]>heap[q+1])
		{
			q++;		
		}

		if(heap[q]>=a)
		{
			break;
		}
		else{
			heap[p]=heap[q];

			p=q;
			q=p*2;	
		}
		heap[p]=a;
		
	}
	
		

}

 

代码虽然很简单,但是思路确实很烦躁,要理解每一步的关键

最后形成的堆是:

 

 

 

 -------更新 2014-11-15 22:00

实现最小堆的目的:堆排序

 

堆排序可以对大量的数据进行查找top k 而不占用大量的内存,原因是不用把数据加载到内存中,读入-堆比较-调整堆,这个流程,只要维护一个最小堆,top k不在话下

 思路:利用最小值堆找出海量数据的前 k个最大值,比堆顶小的数据舍弃,比堆顶大的数据则替换掉堆顶并且向下调整,最后找出top k

#include <iostream>
#include "heap_sort_min.h"
using namespace std;

void main()
{
	int test[]={34,22,145,23,2,35,155,3245,1341,345,889,536,567,3546,786,468,468,464,48,646};
	//int testH[]={24,63,23,47,232,46,12,57,24,74};
	inith(test);
	build();
	for(int i=9;i<20;i++)
		HeapSort(test[i]);
	for(int i=0;i<10;i++)
		cout<<heap[i]<<"  ";
	cout<<endl;

}

 

 

/*堆排序模块*/
void HeapSort(int a)
{
	if(a<heap[0])
		return;
	heap[0]=a;
	down(0);
}

 

 

 

 

 二.指针queue

类似Java的数组队列,而我所称的数组队列并不是严格的FIFO规则,只是一个可增长的动态数组,而指针的细节在于替代了原始地址要释放空间,不然会造成内存泄露

 

 

/*
数组队列
*/

int *array;

int size=10;
int capacity=0;
void queue()
{
	array=new int[10];
}
void add(int data)
{
	int *temp;
	int *at=array;
	if(capacity==size)
	{
		temp=new int[++size];
		for(int i=0;i<capacity;i++)
			temp[i]=array[i];
		temp[size-1]=data;
		array=temp;
		delete[] at;
		capacity++;
	}else{
		array[capacity++]=data;
	
	}


}

 最后一句:人生在于不停地奋斗,没有妹子就要孤独地写代码

<!--EndFragment-->
  • 大小: 19.5 KB
  • 大小: 12.7 KB
  • 大小: 22.8 KB
  • 大小: 26.8 KB
  • 大小: 27.3 KB
分享到:
评论

相关推荐

    STL源码剖析.pdg

    6.6 heap算法:make_heap, pop_heap, push_heap, sort_heap 338 6.7 其它算法 338 6.7.1 单纯的数据处理 338 adjacent_find 343 count 344 count_if 344 find 345 find_if 345 find_end 345 find_first_of ...

    Dijkstra算法求最短路径的C/C++的程序四

    1. **keep_min_heap**:调整最小堆,确保堆的性质(父节点的权值小于或等于子节点)。 2. **heap_insert**:向最小堆中插入新的元素。 3. **heap_extract_min**:从最小堆中删除并返回最小元素。 4. **print_it**:...

    小大根交替堆实现双端优先队列

    `min_max_heap.h`文件则是小大根交替堆的定义和实现,包括堆的构建、调整和操作函数。`studentInfo.h`可能包含了学生信息的结构体定义,如姓名、学号和成绩等,这些信息可能会被用作堆中的元素。`Double_Ended_...

    Huffman树的实现

    1. 创建一个最小堆(Min Heap)或优先队列(Priority Queue),存储所有节点。 2. 将每个字符及其频率作为节点插入到最小堆中。 3. 取出堆顶的两个节点,创建一个新的内部节点,将其设置为这两个节点的父节点,新...

    全面的算法代码库

    最小堆 Min-Heap 乘法逆元 Modular-Multiplicative-Inverse 仅支持单点修改的可持久化线段树(维护区间和值) Persistent-Segment-Tree(Sum) 试除法素数测试 Prime-Check(Naive) 线性的素数筛法 Prime-Sieve...

    嵌入式C语言面试题嵌入式C语言面试题.doc

    局部变量通常存储在堆栈(Stack)中,全局变量存储在静态区(Static Area),动态申请的数据存储在堆(Heap)中。 3. 队列与栈的区别: 队列(Queue)遵循先进先出(FIFO)原则,而栈(Stack)遵循后进先出(LIFO...

    数据结构各种算法实现(C++模板) 数据结构经典实例

    SeqQueue(int capacity = 100) : front(0), rear(0), capacity(capacity), queue(new Type[capacity]) {} ~SeqQueue() { delete[] queue; } bool IsEmpty() const { // 是否为空 return front == rear; } ...

    数据结构与算法常用英语词汇[整理版].doc

    * 最小堆(Min Heap):是一种特殊的堆,父节点的值小于或等于子节点的值。 排序算法 排序算法是将数据元素按照一定的顺序排列的过程。常见的排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序等。 ...

    旅行售货员问题c++源代码及运行结果.docx

    2. **最小堆**(Min Heap):用于存储待扩展的节点,通过`MinHeapNode`结构体实现。结构体包含节点的当前费用`cc`、子树费用的下界`lcost`、从根节点到当前节点的路径`x[s]`、顶点最小出边费用和`rcost`以及指向下一...

    kaiyuzheng_interview_preparation.pdf

    链表是一种线性数据结构,其中的元素不是在内存中连续存储的,而是通过指针链接在一起。链表包括单向链表、双向链表等多种形式。 #### Heap(堆) 堆是一种特殊的树形数据结构,它满足以下性质:每个节点的值都大于...

    计算机编程英语词汇

    2. **链表 (Linked List)**:由节点组成的数据结构,每个节点包含数据和指向下一个节点的指针。 3. **栈 (Stack)**:后进先出(LIFO)的数据结构,主要操作为压栈(push)和弹栈(pop)。 4. **队列 (Queue)**:先进先出...

Global site tag (gtag.js) - Google Analytics