• 排序算法-堆排序


    堆用在动态数据排序中非常合适

    以1索引为开始节点,parent(i) = i /2,left_child (i) =2*i ; right_child(i) = 2*i +1; 最后一个非叶子节点的索引count/2 

    以0索引为开始节点,parent(i) = (i-1)/2, left_child (i) =2*i +1; right_child(i) = 2*i +2; 最后一个非叶子节点的索引(count -1)/2 

    实现一个最大堆

    //最大堆
    template<typename Item>
    class MaxHeap{
    private:
        Item* data;
        int count;
        int capacity;
    
        void shiftUp(int k){
            while(k>1 && data[k/2] < data[k]){
                swap(data[k/2],data[k]);
                k /= 2;
            }
        }
        void shiftDown(int k){
            while (2*k <= count){
                int j = 2*k;
                if(j+1 <= count && data[j+1] >data[j])
                    j+=1
                if(data[k] >= data[j])
                    break;
                swap(data[k],data[j]);
                k=j;
            }
            
        }
    public:
        MaxHeap(int capacity){
            data = new Item[capacity+1];
            count=0;
            this->capacity = capacity;
        }
        ~MaxHeap(){
            delete [] data;
        }
        int size(){
            return count;
        }
        bool isEmpty(){
            return count ==0;
        }
        void insert(Item item){
            assert(count+1 <= capacity);
            data[count +1] = item;
            count++;
            shiftUp(count);
        }
        Item extractMax(){
            assert(count >0);
            Item ret = data[1];
            swap(data[1],data[count]);
            count --;
            shiftDown(1);
            return ret;
        }
    };

     数组变成堆heapify

    #ifndef SELECTIONSORT_HEAP_H
    #define SELECTIONSORT_HEAP_H
    #include <iostream>
    #include <ctime>
    #include <cassert>
    using namespace std;
    
    //最大堆
    template<typename Item>
    class MaxHeap{
    private:
        Item* data;
        int count;
        int capacity;
    
        void shiftUp(int k){
            while(k>1 && data[k/2] < data[k]){
                swap(data[k/2],data[k]);
                k /= 2;
            }
        }
        void shiftDown(int k){
            while (2*k <= count){
                int j = 2*k;
                if(j+1 <= count && data[j+1] >data[j])
                    j+=1
                if(data[k] >= data[j])
                    break;
                swap(data[k],data[j]);
                k=j;
            }
            
        }
    public:
        MaxHeap(int capacity){
            data = new Item[capacity+1];
            count=0;
            this->capacity = capacity;
        }
        //heapfiy
        MaxHeap(Item arr[],int n){
            data = new Item[n+1];
            capacity=n;
            for (int i=0;i<n;i++)
                data[i+1] = arr[i]
            count = n;
            for(int i=count/2;i>=1;i--)
                shiftDown(i);
        }
        ~MaxHeap(){
            delete [] data;
        }
        int size(){
            return count;
        }
        bool isEmpty(){
            return count ==0;
        }
        void insert(Item item){
            assert(count+1 <= capacity);
            data[count +1] = item;
            count++;
            shiftUp(count);
        }
        Item extractMax(){
            assert(count >0);
            Item ret = data[1];
            swap(data[1],data[count]);
            count --;
            shiftDown(1);
            return ret;
        }
    };
    
    #endif

    堆排序实现

    template<typename T>
    void heapSort1(T arr[],int n){
        MaxHeap<T> maxheap = MaxHeap<T>(n);
        for(int i=0;i<n;i++)
            maxheap.insert(arr[i])
        for(int i =n-1;i>=0;i--)
            arr[i] = maxheap.extractMax();
    }
    
    template<typename T>
    void heapSort2(T arr[],int n){
        MaxHeap<T> maxheap = MaxHeap<T>(arr,n);
        for(int i =n-1;i>=0;i--)
            arr[i] = maxheap.extractMax();
    }

     原地堆排序

    template<typename T>
    void __shiftDown(T arr[],int n,int k){
        while (2*k+1 <= n){
                int j = 2*k+1;
                if(j+1 < n && arr[j+1] >arr[j])
                    j+=1
                if(arr[k] >= arr[j])
                    break;
                swap(arr[k],arr[j]);
                k=j;
        }
    }
    
    template<typename T>
    void heapSort(T arr[],int n){
        //heapify
        for(int i =(n-1)/2 ;i>=0;i--)
            __shiftDown(arr,n,i);
        for(int i = n-1;i>0 ;i--)
            swap(arr[0],arr[i]);
            __shiftDown(arr,i,0)
    }

     索引最大堆

    //索引最大堆
    template<typename Item>
    class IndexMaxHeap{
    private:
        Item* data;
        int* indexes;
        int* reverse;
        int count;
        int capacity;
    
        void shiftUp(int k){
            while(k>1 && data[indexes[k/2]] < data[indexes[k]]){
                swap(indexes[k/2],indexes[k]);
                reverse[indexes[k/2]] = k/2;
                reverse[indexes[k]]=k;
                k /= 2;
            }
        }
        void shiftDown(int k){
            while (2*k <= count){
                int j = 2*k;
                if(j+1 <= count && data[indexes[j+1]] >data[indexes[j]])
                    j+=1
                if(data[indexes[k]] >= data[indexes[j]])
                    break;
                swap(indexes[k],indexes[j]);
                reverse[indexes[k]] = k;
                reverse[indexes[j]] = j;
                k=j;
            }
            
        }
    public:
        IndexMaxHeap(int capacity){
            data = new Item[capacity+1];
            indexes = new int[capacity+1];
            reverse = new int[capacity+1];
            for(int i=0;i<=capacity;i++)
                reverse[i]=0;
            count=0;
            this->capacity = capacity;
        }
        ~MaxHeap(){
            delete [] data;
            delete [] indexes;
            delete [] reverse;
        }
        int size(){
            return count;
        }
        bool isEmpty(){
            return count ==0;
        }
        //传入的i对于用户而言,是从0开始索引的
        void insert(int i,Item item){
            assert(count+1 <= capacity);
            assert(i+1 >=1 && i+1 <=capacity);
            i+=1;
            data[1] = item;
            indexes[count+1] = i;
            reverse[i] = count+1;
            count++;
            shiftUp(count);
        }
        Item extractMax(){
            assert(count >0);
            Item ret = data[indexes[1]];
            swap(indexes[1],indexes[count]);
            reverse[indexes[1]] = 1;
            reverse[indexes[count]] = 0;
            count --;
            shiftDown(1);
            return ret;
        }
        int extractMaxIndex(){
            assert(count >0);
            int ret = indexes[1] -1;
            swap(indexes[1],indexes[count]);
            reverse[indexes[1]] = 1;
            reverse[indexes[count]] = 0;
            count --;
            shiftDown(1);
            return ret;
        }
        bool contain(int i){
            assert(i+1 >= 1 && i+1 <= capacity)
            return reverse[i+1] != 0;
        }
        Item getItem(int i){
            assert(contain(i))
            return data[i+1];
        }
    
        void change(int i,Item newItem){
            assert(contain(i))
            i+=1;
            data[i] = newItem;
            //找到indexes[j] = i,j表示data[i]在堆中的位置
            // 之后shiftUp,再shiftDown
            // for(int j =1;j<=count;j++)
            //     if(indexes[j] ==i){
            //         shiftUp(j);
            //         shiftDown(j);
            //         return;
            //     }
            int j  = reverse[i];
            shiftUp(j);
            shiftDown(j);
        }
    };
  • 相关阅读:
    linux的usr目录的全称是什么
    python多线程与多进程及其区别
    redis禁用危险命令
    测试文档
    mysql5.7.23windows安装
    Nginx如何处理手机端和PC端跳转不同页面
    nginx if多条件判断
    centos7单用户模式修改密码
    Django其四
    Django简单搭建编辑页面
  • 原文地址:https://www.cnblogs.com/Erick-L/p/12595129.html
Copyright © 2020-2023  润新知