我与代码的日常:堆的基本操作

学习不易,需要坚持。

#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

typedef int HPDataType ;
typedef struct Heap
{
	HPDataType* array ;
	int size ;
	int capcity ;
}Heap ;

//向下调整
void	AdjustDown(int array[], int size, int root)
{
	int tmp = 0 ; //临时变量
	while(1)
	{
		int left = 2 * root + 1 ;
		int right = 2 * root + 2 ;
		int min = 0 ;
		//若没有左右孩子,直接返回
		if(left >= size)
		{
			//越界
			return ;
		}
		//如果存在右孩子(必有左孩子),则找值最小的孩子
		if(right<size && array[right]<array[left])
		{
			min = right ;
		}
		else
		{
			min = left ;
		}
		//找到最小值后,再判断它与根节点的值
		if(array[root] <= array[min])
		{
			return ;
		}
		else
		{
			tmp = array[root] ;
			array[root] = array[min] ;
			array[min] = tmp ;
			root = min ;
		}
	}
}

//向上调整
void AdjustUp(int array[], int size, int child)
{
	int parent = 0 ; //节点的双亲
	int tmp = 0 ; //临时变量
	while(child != 0)
	{
		parent = (child - 1 ) / 2 ;
		if(array[child] > array[parent])
		{
			return ;
		}
		else
		{
			tmp = array[child] ;
			array[child] = array[parent] ;
			array[parent] = tmp ;
			child = parent ;
		}
	}
}

//建堆,本例子建小堆
void CreatHeap(int array[], int size)
{
	//从最后一个非叶子节点开始,一直调整到array[0]结束,
	//最后一个非叶子节点为最后一个节点的双亲节点
	int i = 0 ;
	for(i=(size-2)/2; i>=0; i--)
	{
		AdjustDown(array,size,i) ;
	}
}

void HeapCreatHeap(Heap* heap, int array[], int size)
{
	int i = 0 ;
	heap->capcity = size * 2 ;
	heap->size = size ;
	heap->array = (int *) malloc (sizeof(int) * size) ;
	for(i=0; i<size; i++)
	{
		heap->array[i] = array[i] ;
	}
	CreatHeap(heap->array, heap->size ) ;
}

//增加元素
void HeapInsert(Heap* heap, int val)
{
	heap->array[heap->size] = val ;
	heap->size++ ;
	AdjustUp(heap->array, heap->size, heap->size - 1) ; //size-1就是 child
}

//删除元素(只能删除堆顶元素)
void HeapPop(Heap* heap)
{
	//堆的删除元素算法思想:将最后一个元素覆盖原堆顶元素,再从array[0]进行调整
	assert(heap->size > 0) ;
	heap->array[0] = heap->array[heap->size - 1] ;
	heap->size-- ;
	AdjustDown(heap->array, heap->size, 0) ;
}

//返回堆顶元素值
HPDataType HeapTop(Heap* heap)
{
	assert(heap->size > 0) ;
	return heap->array[0] ;
}

//打印
void HeapPrint(Heap* heap, int size)
{
	int i = 0 ;
	for(i=0; i<heap->size; i++)
	{
		printf("%d ", heap->array[i]) ;
	}
	printf("\n") ;
}

void Test()
{
	Heap heap ;
	int array[] = {3, 9, 1, 7, 5, 8, 14, 13, 2, 6, 9} ;
	int size = sizeof(array) / sizeof(array[0]) ;
	HeapCreatHeap(&heap, array, size) ;


	//打印初始的堆
	printf("建好的堆为: \n") ;
	HeapPrint(&heap, size) ;

	//在堆里插入一个元素
	HeapInsert(&heap, 15) ;
	printf("\n插入15后:\n") ;
	HeapPrint(&heap, size) ;
    
	// 返回新堆的堆顶元素
	printf("\n插入15后,堆顶元素为: %d\n", HeapTop(&heap)) ;

	//再在堆里插入一个元素
	HeapInsert(&heap, 0) ;
	printf("\n再插入0后的堆为:\n") ;
	HeapPrint(&heap, size) ;

	printf("插入0后,堆顶元素为: %d\n", HeapTop(&heap)) ;

	printf("\n建堆成功!\n") ;
}

int main()
{
	Test() ;
	printf("\n") ;
	return 0 ;
}

运行结果:
在这里插入图片描述

学习不易,需要坚持。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章