zoukankan      html  css  js  c++  java
  • 堆:将数据按完全二叉树的顺序存储方式存储在一维数组

    数组中的数据值同时满足 a[i]>=2a[i]+1 和  a[i]>=2a[i]+2

    或者同时满足a[i]<=2a[i]+1 和 a[i]<=2a[i]-1

    堆的特性:是完全二叉树

    大堆,每个双亲节点的值总是大于(等于)子节点的值。

    小堆,每个双亲节点的值总是小于(等于)子节点的值。

    数据结构中的堆和内存中的堆的区别:

    数据结构中的堆是一种数据的存储结构,是算法,而内存堆区是内存中区别于栈区、静态常量区的一个数据存储区域。

    创建堆:讲数组(序列)在逻辑上看成完全二叉树,然后通过算法从倒数第一个非叶子节点进行调整,最后得到堆。

    插入元素时:将元素插入到数组的尾上,然后将其与父节点对比向上调整。

    删除:将顶元素与最后一个元素交换,再进行调整,最后将记录元素个数的那个值减1

    堆排序:有两种,1 将数组放到堆中,一次取堆顶元素放回数组,并删除对顶元素    (额外开辟空间)

                                 2  将数组放到堆中,调整完后形成需要的堆,然后依次取堆顶元素  (不开辟空间,浪费时间)

    TOPk问题,取前面的几个数据建小堆,后面的数据和堆中的数据对比,大于堆顶则替换堆顶元素,然后向下调整

    
    

    typedef int DataType;

    typedef struct Heap 

       {  

                 int *arr;  

                 int capacity;  

                 int size;

    }Heap;

    // 销毁堆 
    void DestroyHeap(Heap* heap)
    {
    	if (heap == NULL)
    	{
    		return;
    	}
    	//capacity和数组可以不用再管
    	heap->size = 0;
    	return;
    }
    
    // 获取堆中有效元素个数 
    int SizeHeap(Heap* heap)
    {
    	if (heap == NULL)
    	{
    		return 0;
    	}
    	return heap->size;
    }
    
    // 检测堆是否为空 
    int EmptyHeap(Heap* heap)
    {
    	if (heap == NULL)
    	{
    		return 0;
    	}
    	return heap->size == 0 ? 1 : 0;
    }
    
    //堆化
    void heapify(int a[], int size, int index) {
    	// index 是不是叶子结点? index 有没有孩子?
    	// index 有没有左孩子? index 左孩子下标是否越界?
    	if (2 * index + 1 >= size) 
    	{
    		return;
    	}
    
    	int min = 2 * index + 1;
    	if (2 * index + 2 < size && a[2 * index + 2] < a[2 * index + 1]) {
    		min = 2 * index + 2;
    	}
    
    	if (a[index] <= a[min])
    	{
    		return;
    	}
    
    	int t = a[min];
    	a[min] = a[index];
    	a[index] = t;
    
    	heapify(a, size, min);
    }
    
    void HeapInit(Heap *heap, int a[], int size) {
    	for (int i = 0; i < size; i++) {
    		heap->arr[i] = a[i];
    	}
    	heap->size = size;
    
    	createHeap(heap->arr, heap->size);
    }
    
    
    void adjustUp(int a[], int index) {
    	while (index > 0) {
    		if (index == 0) {
    			return;
    		}
    
    		int parent = (index - 1) / 2;
    		if (a[parent] <= a[index]) {
    			return;
    		}
    
    		int t = a[parent];
    		a[parent] = a[index];
    		a[index] = t;
    
    		index = parent;
    	}
    }
    
    void HeapPush(Heap *heap, int val) {
    	heap->arr[heap->size++] = val;
    	adjustUp(heap->arr, heap->size - 1);
    }
    
    void HeapPop(Heap *heap) {
    	assert(heap->size > 0);
    	heap->arr[0] = heap->arr[heap->size - 1];
    	heap->size--;
    
    	heapify(heap->arr, heap->size, 0);
    }
    
    
    void createHeap(int arr[], int size)
    {
    	//(size-2)/2 划分开始的界限,从最后一个非叶节点
    	for (int i = (size - 2) / 2; i >= 0; i--)
    	{
    		int index = i;
    		while (1) {
    			int left = 2 * index + 1;
    			int right = 2 * index + 2;
    
    			if (left >= size) {
    				return;
    			}
    
    			int min = left;
    			if (right < size && arr[right] < arr[left]) {
    				min = right;
    			}
    
    			if (arr[index] <= arr[min]) {
    				return;
    			}
    
    			int t = arr[min];
    			arr[min] = arr[index];
    			arr[index] = t;
    
    			index = min;
    		}
    	}
    }
    
    int main()
    {
    	int arr[10] = { 5, 2, 6, 9, 8, 3, 0, 4, 1, 7 };
    	int size = sizeof(arr) / sizeof(arr[0]);
    	//Heap* 
    	createHeap(arr, size);
    	
    
    	return 0;
    }
    
    住进火焰就成为萤火虫。
  • 相关阅读:
    Eclipse中的常见设置
    Maven配置及使用总结
    启动Eclipse时,出现 “Failed to load the JNI shared library "C:Program Filesjavajdk1.7.....jvm.dll"
    Java 环境问题汇总
    Java 异常处理
    Java面向对象(二)
    Java面向对象(一)
    Java获取路径
    Java代码读取文件
    工作常用快捷键大全
  • 原文地址:https://www.cnblogs.com/fengkun/p/11241221.html
Copyright © 2011-2022 走看看