最大(小)堆初始化,插入,删除,及利用其排序实现

#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define esp 1e-8
//#define lson   l, m, rt<<1
//#define rson   m+1, r, rt<<1|1
#define sz(x) ((int)((x).size()))
#define pf(x) ((x)*(x))
#define pb push_back
#define pi acos(-1.0)
#define in freopen("solve_in.txt", "r", stdin);
#define out freopen("solve_out.txt", "w", stdout);
#define bug(x) cerr << "Line : " << (x) <<  " >>>>>>\n";
#define TL cerr << "Time elapsed: " << (double)clock() / CLOCKS_PER_SEC * 1000 << " ms" << endl;
#define inf 0x0f0f0f0f

using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef map<LL, int> MPS;
typedef pair<int, int> PII;
typedef MPS::iterator IT;
class maxHeap {
public:
    vector<int> heap;
    int n;
    void init(vector<int> arr) {
        this->n = sz(arr);
        heap.resize(n+1);//heap[1...n]存放元素;
        for(int index = 1; index <= n; index++) {
            heap[index] = arr[index-1];
        }
        int id = n;
        while(id > 1) {
            heapDown(id/2);
            id -= 2;
        }
    }
    void heapDown(int rt) {
//        cout << rt << endl;
        if(rt > n) return;
        int lson = rt<<1;
        int rson = rt<<1|1;
        if(lson > n) return;
        if(rson > n || heap[rson] < heap[lson]) {
            if(heap[rt] < heap[lson]) {
                swap(heap[rt], heap[lson]);
                heapDown(lson);
            }
        } else  {
           if(heap[rt] < heap[rson]){
            swap(heap[rt], heap[rson]);
            heapDown(rson);
           }
        }
    }
    void heapUp(int rt) {
        while(rt > 1 && heap[rt] > heap[rt/2]) {
            swap(heap[rt], heap[rt/2]);
            rt /= 2;
        }
    }
    void insertHeap(int value) {
        heap.pb(value);
        n++;
        heapUp(n);
    }
    void deleteHeap(int pos) {
        if(pos == n) {
            heap.pop_back();
            n--;
        } else {
            swap(heap[pos], heap[n]);
            heap.pop_back();
            n--;
            if(pos == 1 || heap[pos] < heap[pos/2]) {
                heapDown(pos);
            } else {
                heapUp(pos);
            }
        }
    }
    int getMaxValue() {
        if(n >= 1) return heap[1];
        return -inf;
    }
    vector<int> getSortedList() {
        maxHeap tmpHeap = *this;
        vector<int> ans;
        while(tmpHeap.n) {
            ans.pb(tmpHeap.getMaxValue());
            tmpHeap.deleteHeap(1);
        }
        return ans;
    }
    void print() {
        vector<int> vec = getSortedList();
        for(int i = 0; i < sz(vec); i++)
            printf("%d%c", vec[i], i != sz(vec)-1 ? ‘ ‘ : ‘\n‘);
    }
    void printHeap() {
        for(int i = 1; i <= n; i++)
            printf("%d%c", heap[i], i != n ? ‘ ‘ : ‘\n‘);
    }
} solver;
int main() {
    in
    int n;
    vector<int> vec;
    cin >> n;
    for(int i = 0; i < n; i++) {
        int u;
        scanf("%d", &u);
//        cout << u << endl;
        vec.pb(u);
    }
    solver.init(vec);
    solver.printHeap();
    solver.insertHeap(80);
    solver.printHeap();
    solver.deleteHeap(2);
    solver.printHeap();
    solver.deleteHeap(2);
    solver.printHeap();
    solver.print();

    return 0;
}

时间: 2024-10-31 12:39:10

最大(小)堆初始化,插入,删除,及利用其排序实现的相关文章

双向循环链表 初始化 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(DuLNode)

顺序表 初始化 插入 删除 查找 合并 交换 判断为空 求长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(SqList) #define MLC (Li

数据结构之堆的插入、取值、排序(细致讲解+图片演示)

数据结构之堆(Heap):插入.取值.排序. 堆是一种数据结构,分为最小堆和最大堆,可以用二叉树来表示. 在二叉树的任意的一个三角结构中(一个父节点,两个子节点),需要满足以下两个条件: 1.父节点要是最小的,就是最小堆(或最大的,就是最大堆),两个子节点之间没有要求 2.数据插入的顺序是一层一层的,只有上一层存满,才会有下一层 下面我们以图片的形式演示最小堆的插入.取值.和排序操作,只要知道最小堆的原理,那么最大堆也就明白了. 假设我们有一个原始的最小堆如下: 插入操作: 当插入一个新值时,首

(透彻理解)最精锐代码::堆的三种基本操作新建-插入-删除

1.删除堆顶的最大元素 (以某个元素为根结点向下调整为堆) 比如:删除这个堆的20 第一步:是20 和 3 交换 第二步:以3为根节点开始调整为堆(3和17交换) 再以3为根节点调整为堆(16和3交换)这样又形成了一个堆 2.往一个完整的堆中插入元素(唯一一个自底向上调整的例子) 目标:往堆的尾部插入元素21,这样就破坏了堆,然后要调整为堆 算法1:21和8调整   这样20的左右是一个堆了 算法2:将21和20进行调整,这样堆就形成了 3.新建一个堆(以某个元素为根结点向下调整为堆) 算法1:

静态链表 初始化 定位 Malloc Free 插入 删除

#include <stdio.h> #include <stdlib.h> #define OK 1 #define TRUE 1 #define ERROR -1 #define FALSE -1 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define MAX_SIZE 1000;//表最大空间 /* //线性表的基本操

堆的插入、删除和建立操作,堆排序

1.        堆 堆:n个元素序列{k1,k2,...,ki,...,kn},当且仅当满足下列关系时称之为堆: (ki <= k2i,ki <= k2i+1) 或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4,...,n/2) 若将和此次序列对应的一维数组(即以一维数组作此序列的存储结构)看成是一个完全二叉树,则堆的含义表明,完全二叉树中所有非终端结点的值均不大于(或不小于)其左.右孩子结点的值.由此,若序列{k1,k2,…,kn}是堆,则堆顶元

单链表 初始化 创建 头插法 尾插法 插入 删除 查找 合并 长度

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE -1 #define NULL 0 #define OVERFLOW -2 #define ElemType int #define Status int typedef int ElemType typedef int Status #define LEN sizeof(LNode) #

堆排序--采用快速排序(利用大堆实现升序,小堆实现降序)

对堆进行排序,利用大堆实现升序,小堆实现降序.例如升序的实现,将较大数据存放在最后面,依次往前存放数据.具体为交换第一个元素和最后一个元素,再将不包含最后一个元素的堆进行下调,使堆保持大堆,将最大数据存放在堆中第一个位置,循环执行上述步骤,直到需要下调的数据个数为0. void AdjustDown(int *a, size_t root, size_t size)//下调--k为数组下标,size为数组元素个数 {//大堆 size_t parent = root; size_t child 

C语言双向链表简单实现及图示(初始化/插入节点/删除节点)

-------------------------------------------- 双向链表 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 和单向链表相比有以下优势: 插入删除不需要移动元素外,可以原地插入删除 可以双向遍历 - - - - -

[转]C++ STL list的初始化、添加、遍历、插入、删除、查找、排序、释放

list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入删除元素. 使用list容器之前必须加上STL的list容器的头文件:#include<list>; list属于std命名域的内容,因此需要通过命名限定:using std::list;也可以直接使用全局的命名空间方式:using namespace std; (1)初始化 typedef struct info_s { int nNu