码迷,mamicode.com
首页 > 其他好文 > 详细

heap sort

时间:2018-07-22 23:34:35      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:hat   ram   nbsp   2.4   value   word   等于   最小堆   math   

堆是具有下列性质的完全二叉树

每个结点的值L[i]L[i]都大于或等于其左孩子L[left(i)]L[left(i)]和右孩子L[right(i)]L[right(i)]结点的值,称为大顶堆(最大堆); 
每个结点的值L[i]L[i]都小于或等于其左孩子L[left(i)]L[left(i)]和右孩子L[right(i)]L[right(i)]结点的值,称为小顶堆(最小堆);

分为大根堆和小根堆

二叉堆在内存中是用数组存储的。 
??如果堆的根结点为L[0]i结点的父结点下标就为?(i1)/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[i]都大于或等于其左孩子L[left(i)]L[left(i)]和右孩子L[right(i)]L[right(i)]结点的值,称为大顶堆(最大堆); 
每个结点的值L[i]L[i]都小于或等于其左孩子L[left(i)]L[left(i)]和右孩子L[right(i)]L[right(i)]结点的值,称为小顶堆(最小堆);

heap sort

标签:hat   ram   nbsp   2.4   value   word   等于   最小堆   math   

原文地址:https://www.cnblogs.com/guxuanqing/p/9351740.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!