zoukankan      html  css  js  c++  java
  • 堆排序

    问题描述:

    堆排序

    问题解决:

    堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

    堆节点的访问

    通常堆是通过一维数组来实现的。在起始数组为 0 的情形中:

    • 父节点i的左子节点在位置 (2*i+1);
    • 父节点i的右子节点在位置 (2*i+2);
    • 子节点i的父节点在位置 floor((i-1)/2);

    堆的操作

    在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义以下几种操作:

    • 最大堆调整(Max_Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
    • 创建最大堆(Build_Max_Heap):将堆所有数据重新排序
    • 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算

    image

    堆排序算法时间复杂度:O(N * logN)

    具体实现:

    #ifndef HEADSORT_H
    #define HEADSORT_H
    
    #include<iostream>
    #include <cmath>
    #include <assert.h>
    using namespace std;
    
    #define BIGEST        ((unsigned)(~0)>>1)
    #define SMALLEST    ~BIGEST
    
    class HeapSort
    {
    private:
        int* arr;    
        int len;
    
        inline void swap(int& a,int&b)
        {
            int temp=a;
            a=b;
            b=temp;
        }
    
        inline int  parrent(int i)
        {
            return floor((double)i/2);
        }
    
        inline int lchild(int i)
        {
            return 2*i;
        }
    
        inline int rchild(int i)
        {
            return 2*i+1;
        }
    
        /**
        *    单个节点的最大堆调整
        */
        void MaxHeapify(int *array,int i)
        {
            int largest=i;
            assert(i<len);
    
            int l=lchild(i);
            if (l<=len && array[largest]< array[l])
            {
                largest=lchild(i);
            }
    
            int r=rchild(i);
            if (r<=len && array[largest]<array[r])
            {
                largest=rchild(i);
            }
    
            if (largest!=i)
            {
                swap(array[i],array[largest]);
                MaxHeapify(array,largest);
            }
        }
    
        /**
        *    所有元素最大堆调整
        */
        void MaxSort(int *smax)
        {
            memcpy(smax,arr,(len+1)*sizeof(int));
            for (int i=parrent(len);i>0;i--)
            {
                MaxHeapify(smax,i);
            }
        }
    
        /**
        *    单个节点小根堆调整
        */
        void MinHeapify(int *array,int i)
        {
            assert(i<=len);
            int minimum=i;
    
            int l=lchild(i);
            if (l<=len && array[l]<array[minimum])
            {
                minimum=l;
            }
    
            int r=rchild(i);
            if (r<=len && array[r]<array[minimum])
            {
                minimum=r;
            }
    
            if (minimum!=i)
            {
                swap(array[minimum],array[i]);
                MinHeapify(array,minimum);
            }
        }
    
        /**
        *    所有元素最小堆调整
        */
        void MinSort(int* smin)
        {
            memcpy(smin,arr,(len+1)*sizeof(int));
            for (int i=parrent(len);i>0;i--)
            {
                MinHeapify(smin,i);
            }
        }
    
    public:
        HeapSort(int *array,int length=100)
        {
            len=length;
            this->arr=new int[len+1];
            this->arr[0]=0;    //数组第一个空出,元素从1开始编号
            memcpy(this->arr+1,array,len*sizeof(int));
        }
    
        /**
        *    输出原始数组
        */
        void getOringin()
        {
            for (int i=0;i<=len;i++)
            {
                cout<<arr[i]<<"	";
            }
        }
    
        /**
        *    输出大根堆
        */
        void getMaxHeap()
        {
            int *smax=new int[len+1];
            MaxSort(smax);
            for (int i=len;i>=1;i--)
            {
                cout<<smax[1]<<"	";
                smax[1]=SMALLEST;
                swap(smax[1],smax[i]);
                MaxHeapify(smax,1);
            }
         delete smax;  //记住释放空间 cout
    <<endl; } /** * 输出小根堆 */ void getMinHeap() { int *smin=new int[len+1]; MinSort(smin); for (int i=len;i>0;i--) { cout<<smin[1]<<" "; smin[1]=BIGEST; swap(smin[i],smin[1]); MinHeapify(smin,1); }
        delete smin;  //记住释放空间 cout
    <<endl; }

      //记住要析构  
      ~HeapSort()
      {
        delete arr;
      }
    };
    #endif

    main函数:

    #include "heap.h"
    
    int main()
    {
        int A[]={78,14,8,89,75,71,44,68,33};
        HeapSort heap(A,sizeof(A)/sizeof(int));
    
        cout<<"Origin:"<<endl;
        heap.getOringin();
    
        cout<<"Max Heapify:"<<endl;
        heap.getMaxHeap();
    
        cout<<"Min Heapify:"<<endl;
        heap.getMinHeap();
    }
  • 相关阅读:
    Android仿qq聊天记录长按删除功能效果
    charles工具抓包教程(http跟https)
    瀑布流StaggeredGridView 下拉刷新
    Android微信分享图片大于32k进行压缩
    Android使用TextureView播放视频
    ViewPager+RadioGroup实现标题栏切换,Fragment切换
    android:theme决定AlertDialog的背景颜色
    实现本地音乐选择,播放,带可拖动进度条
    android图片透明度跟缩放大小动画事件
    Android中实现双击事件
  • 原文地址:https://www.cnblogs.com/luosongchao/p/3400044.html
Copyright © 2011-2022 走看看