标签:hat ram nbsp 2.4 value word 等于 最小堆 math
堆是具有下列性质的完全二叉树:
每个结点的值L[i]都大于或等于其左孩子L[left(i)]和右孩子L[right(i)]结点的值,称为大顶堆(最大堆);
每个结点的值L[i]都小于或等于其左孩子L[left(i)]和右孩子L[right(i)]结点的值,称为小顶堆(最小堆);
分为大根堆和小根堆
二叉堆在内存中是用数组存储的。
??如果堆的根结点为L[0],i结点的父结点下标就为?(i–1)/2?。i结点的左右子结点下标分别为(2?i+1)和(2?i+2)。如下图(b)所示。
如果堆的根结点为L[1],i结点的父结点下标就为?i/2?。i结点的左右子结点下标分别为(2?i)和(2?i+1)。
一般而言,从下到上,从右到左建堆.
// returns the left node (by doubling the current node) int leftNode ( int node) { return node << 1 ; // this actually does 2*node } // returns the right node (by doubline the current node and adding 1) int rightNode ( int node) { return (node << 1) + 1 ; // this actually does 2*node+1 } // return the parent node (by taking the half of the // current node and returning its floor) int parentNode ( int node) { return ( int )floor(node / 2) ; } // restore the heap property void maxHeapify ( int array[], int i, int heapSize) { // get the two children nodes int left = leftNode(i) ; int right = rightNode(i) ; // assume that the largest is originally the current node int largest = i ; // check if the left node is the largest if (left <= heapSize && array[left] > array[i]) largest = left ; // check if the right node is the largest if (right <= heapSize && array[right] > array[largest]) largest = right ; // in case the left or right node was larger than the parent if (largest != i) { // we switch the parent with the largest child int temp = array[i] ; array[i] = array[largest] ; array[largest] = temp ; // and apply maxHeapify recursively to the subtree maxHeapify(array, largest, heapSize) ; } } // build the heap by looping through the array void buildMaxHeap ( int array[], int heapSize) { for ( int i = ( int )floor(heapSize / 2) ; i >= 0 ; i -- ) maxHeapify(array, i, heapSize) ; } void heapSort ( int array[], int arraySize) { // determine the heap size int heapSize = arraySize ; // build the heap buildMaxHeap(array, heapSize) ; // loop through the heap for ( int i = heapSize ; i > 0 ; i -- ) { // swap the root of the heap with the last element of the heap int temp = array[0] ; array[0] = array[i] ; array[i] = temp ; // decrease the size of the heap by one so that the previous // max value will stay in its proper placement heapSize -- ; // put the heap back in max-heap order maxHeapify(array, 0, heapSize) ; } }
method 2
#include <stdio.h> #include <stdlib.h> int arrtest[100]; void swap(int *a,int *b) { int temp=*a; *a=*b; *b=temp; } void maxHeapify(int arr[],int i,int heapsize) { //维护堆的性质,可以用非递归实现 int left=2*i+1; int right=2*i+2; int largest; if (left<=heapsize && arr[left]>arr[i]) largest=left; else largest=i; if (right<=heapsize && arr[right]>arr[largest]) largest=right; if(largest!=i) { swap(&arr[largest],&arr[i]); maxHeapify(arr,largest,heapsize); } } void buildMaxHeap(int arr[],int heapsize) { //建堆 for(int i=(heapsize-1)/2; i>=0; i--) { maxHeapify(arr,i,heapsize); } } void heapSort(int arr[],int len) { //堆排序 buildMaxHeap(arr,len-1); for(int i=len-1; i>0; i--) { swap(&arr[0],&arr[i]); //buildMaxHeap(arr,i-1);//此处无需从新建堆,从新维护堆性质即可 maxHeapify(arr,0,i-1); } } void PrintArray(int arr[],int length) { //打印数组,用于查看排序效果 printf("["); for(int i=0; i<length; i++) { if(i==length-1) printf("%d]\n",arr[i]); else printf("%d ,",arr[i]); } } int main() { int num=0; printf("请输入数组元素个数:"); scanf("%d",&num); for(int i=0; i<num; i++) { //读入待排序数据 scanf("%d",&arrtest[i]); } printf("排序前数据为:"); PrintArray(arrtest,num); heapSort(arrtest,num); printf("排序后数据为:"); PrintArray(arrtest,num); return 0; }
堆是具有下列性质的完全二叉树:
每个结点的值L[i]都大于或等于其左孩子L[left(i)]和右孩子L[right(i)]结点的值,称为大顶堆(最大堆);
每个结点的值L[i]都小于或等于其左孩子L[left(i)]和右孩子L[right(i)]结点的值,称为小顶堆(最小堆);
标签:hat ram nbsp 2.4 value word 等于 最小堆 math
原文地址:https://www.cnblogs.com/guxuanqing/p/9351740.html