zoukankan      html  css  js  c++  java
  • heap sort

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

    每个结点的值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)/2i结点的左右子结点下标分别为(2i+1)(2i+2)。如下图(b)所示。

    如果堆的根结点为L[1]i结点的父结点下标就为i/2i结点的左右子结点下标分别为(2i)(2i+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]
    ",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)]结点的值,称为小顶堆(最小堆);

  • 相关阅读:
    暑假团队学习第一周
    Python快速入门(3)
    Python快速入门(2)
    走入PHP-类与对象
    走入PHP-declare、ticks、encoding、include
    走入PHP-变量、运算符
    XAMPP安装报错及解决
    走入PHP-数据类型和字符串语法
    走入PHP-初次见面
    剑指offer-替换空格
  • 原文地址:https://www.cnblogs.com/guxuanqing/p/9351740.html
Copyright © 2011-2022 走看看