博客
关于我
堆的操作与应用1 -C++
阅读量:799 次
发布时间:2019-03-25

本文共 2905 字,大约阅读时间需要 9 分钟。

堆的实现与应用

堆是一种非常有趣且重要的数据结构,它以其特殊的性质,使得许多高效算法成为可能。尤其在编程问题中,堆常常被用来解决排序问题,或者用来实现优先队列的功能。在本文中,我们将深入探讨堆的实现以及它在实际问题中的应用。


堆的初始化

堆的初始化可以通过调整的过程来完成。每当一个元素插入堆之后,需要确保该元素的位置是否满足堆的性质。如果不满足,进行调整直到满足为止。

void heap_adjust(int x) {    while (x * 2 <= tot) {        int j = x * 2;        if (j + 1 <= tot && heap[j + 1] > heap[j]) {            j++;        }        if (heap[j] > heapp[x]) {            swap(heap[x], heap[j]);            x = j;        } else {            break;        }    }}void Adjust(int tot) {    for (int i = tot / 2; i >= 1; i--) {        heap_adjust(i);    }}

合并果子(朴素版本)

在某些问题中,例如合并两个有序链表,我们可以用堆来实现。以下是一个朴素的合并示例,使用堆来合并两个有序序列:

#include 
#include
#include
using namespace std;void upload_Lb(int k) { while (k > 1) { if (h[k / 2] > h[k]) { swap(h[k / 2], h[k]); k /= 2; } else { return; } }}void down(int k) { while (2 * k <= tot) { int j = 2 * k; if (j < tot && h[j + 1] < h[j]) { j++; } if (h[j] < h[k]) { swap(h[j], h[k]); k = j; } else { return; } }}int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) { int x; scanf("%d", &x); h[i] = x; tot++; up(tot); } for (int i = 1; i < n; i++) { int tmp = h[1]; h[1] = h[tot--]; down(1); tmp += h[1]; h[1] = h[tot--]; down(1); ans += tmp; h[++tot] = tmp; up(tot); } printf("%d", ans); return 0;}

STL - priority_queue

在C++标准库中,priority_queue 提供了优先队列的实现,可以根据需求选择升序队列或降序队列。以下是 priority_queue 的基本用法示例:

#include 
using namespace std;// 升序队列priority_queue
, greater
> q;// 插入元素q.push(5);// 获取顶部元素q.top();// 删除顶部元素q.pop();// 获取队列大小q.size();

堆排序

堆排序是一种优化排序算法,利用了堆的性质来进行排序。其步骤如下:

  • 建立初始大顶堆:将数组调整为大顶堆。
  • 交换并调整:每次交换第一个元素和最后一个元素,重新调整堆结构。
  • 重复上述步骤,直到所有元素都被排序。
  • 以下是具体实现代码:

    #include 
    #include
    using namespace std;void max_heapify(int arr[], int start, int end) { int dad = start; int son = dad * 2 + 1; while (son <= end) { if (son + 1 <= end && arr[son] < arr[son + 1]) { son++; } if (arr[dad] > arr[son]) { return; } else { swap(arr[dad], arr[son]); dad = son; son = dad * 2 + 1; } }}void heap_sort(int arr[], int len) { for (int i = len / 2 - 1; i >= 0; i--) { max_heapify(arr, i, len - 1); } for (int i = len - 1; i > 0; i--) { swap(arr[0], arr[i]); max_heapify(arr, 0, i - 1); }}int main() { int arr[] = {3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6}; int len = sizeof(arr) / sizeof(*arr); heap_sort(arr, len); for (int i = 0; i < len; i++) { cout << arr[i] << ' '; } cout << endl; return 0;}

    转载地址:http://yfsyk.baihongyu.com/

    你可能感兴趣的文章
    MSEdgeDriver (Chromium) 不适用于版本 >= 79.0.313 (Canary)
    查看>>
    MsEdgeTTS开源项目使用教程
    查看>>
    msf
    查看>>
    MSSQL数据库查询优化(一)
    查看>>
    MSSQL数据库迁移到Oracle(二)
    查看>>
    MSSQL日期格式转换函数(使用CONVERT)
    查看>>
    MSTP多生成树协议(第二课)
    查看>>
    MSTP是什么?有哪些专有名词?
    查看>>
    Mstsc 远程桌面链接 And 网络映射
    查看>>
    Myeclipse常用快捷键
    查看>>
    MyEclipse更改项目名web发布名字不改问题
    查看>>
    MyEclipse用(JDBC)连接SQL出现的问题~
    查看>>
    mt-datetime-picker type="date" 时间格式 bug
    查看>>
    myeclipse的新建severlet不见解决方法
    查看>>
    MyEclipse设置当前行背景颜色、选中单词前景色、背景色
    查看>>
    Mtab书签导航程序 LinkStore/getIcon SQL注入漏洞复现
    查看>>
    myeclipse配置springmvc教程
    查看>>
    MyEclipse配置SVN
    查看>>
    MTCNN 人脸检测
    查看>>
    MyEcplise中SpringBoot怎样定制启动banner?
    查看>>