堆排序

堆排序:从小到大(小顶堆:依次pop出最小的元素)

方法1:基于堆的插入insert和删除pop两个操作进行的:先将数组中要排序的数值依次插入到小顶堆vec中,全部插入后,再将小顶堆的顶部数值依次pop出来,将剩余的元素形成小顶堆,再pop出第二小的元素。。。以此类推。

此时,需要在class中新建两个vector成员变量用于保存插入进来的值和pop出去的最小值

#include <iostream>
#include <vector>
using namespace std;

class heap_sort{
public:
    vector<int> vec;
    vector<int> res;
    void insert(int val){  //将数值插入到成员变量vec中,使得存入的数在vec中形成小顶堆
        vec.push_back(val);
        int index=vec.size()-1;
        int father=(index-1)/2;
        while(index>0){
            if(vec[index]<vec[father]){
                swap(vec[index],vec[father]);
                index=father;
                father=(index-1)/2;
            }
            else
                break;
        }
    }
    void swap(int &val1,int &val2){
        int temp=val1;
        val1=val2;
        val2=temp;
    }
    void pop(){   //将class中的成员变量vec中的顶部值pop出来,放入res中,然后再将vec剩余的元素组装成小顶堆
            res.push_back(vec[0]);      //最终成员变量res中即为从小到大的排列
            vec[0]=vec[vec.size()-1];
            vec.pop_back();
            int max_index=vec.size()-1;
            int index=0;
            int lchild;
            int rchild;
            while(index<max_index){
                lchild=index*2+1;
                rchild=index*2+2;
                if(lchild>max_index){
                    break;
                }
                else if(rchild>max_index){
                    if(vec[index]>vec[lchild]){
                        swap(vec[index],vec[lchild]);
                        index=lchild;
                    }
                    else
                        break;
                }
                else{
                    int bigger=vec[lchild]<vec[rchild]?lchild:rchild;
                    if(vec[index]>vec[bigger]){
                        swap(vec[index],vec[bigger]);
                        index=bigger;
                    }
                    else
                        break;
                }
            }
        }
};

int main() {
    heap_sort s;
    int a[5]={4,6,8,5,9};
   for(int i=0;i<5;i++){   //首先将main函数中数组中的值一个一个插入到class heap_sort的成员变量vec中,形成一个小顶堆
        s.insert(a[i]);
   }
    for(int i:s.vec){
        cout<<i<<",";
    }
    cout<<endl;
    for(int i=0;i<5;i++){  //将class heap_sort的成员变量vec小顶堆中顶部值pop出来,存到res容器中
        s.pop();
    }
    for(int i:s.res){   //最终我们需要的从小到大的排列数组保存在res容器中
        cout<<i<<",";
    }
    return 0;

}

方法2:直接对外部传进来的vector进行操作,但要注意传入的是vector的引用,否则外部的vector中的值不会改变。

       1. 将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;

  2.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;

  3.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。

#include <iostream>
#include <vector>
using namespace std;

class Heap_sort{

public:
//    vector<int> heap;
//    Heap_sort(vector<int> vec){
//        heap = vec;
//    }

    vector<int> sort(vector<int> &heap) {  //此处传入的是vector的引用
        int size=heap.size();
        for(int i=(size/2-1);i>=0;i--){
            excute(heap, i, size - 1);
        }
        for(int j=size-1;j>0;j--){
            swap(heap[0],heap[j]);
            excute(heap, 0, j - 1);
        }
        return heap;
    }
    void excute(vector<int> &vec, int i, int size){   //此处传入的是vector的引用
        int lchild,rchild,max_index;
        while(i<size){
            lchild=i*2+1;
            rchild=i*2+2;
            if(lchild>size){
                break;
            }
            else if(rchild>size){
                if(vec[i]<vec[lchild]){
                    swap(vec[i],vec[lchild]);
                    i=lchild;
                }
                else
                    break;
            }
            else{
                max_index=vec[lchild]>vec[rchild]?lchild:rchild;
                if(vec[i]<vec[max_index]){
                    swap(vec[i],vec[max_index]);
                    i=max_index;
                }
                else
                    break;
            }
        }
    }
    void swap(int &val1,int &val2){
        int temp=val1;
        val1=val2;
        val2=temp;
    }

};

int main() {
    int a[5]={4,6,8,5,9};
    vector<int> vec(begin(a),end(a));
    Heap_sort s;
    vec=s.sort(vec);
    for (int i:vec) {
        cout<<i<<endl;
    }
    return 0;
}

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页