数据结构:堆(堆排序和模拟堆)

1.堆排序

输入一个长度为n的整数数列,从小到大输出前m小的数。

输入格式
第一行包含整数n和m。
第二行包含n个整数,表示整数数列。

输出格式
共一行,包含m个整数,表示整数数列中前m小的数。

数据范围
1≤m≤n≤10^5,
1≤数列中元素≤10^9
输入样例:
5 3
4 5 1 3 2
输出样例:
1 2 3

算法的基本思想:
按完全二叉树存放数据,则数据中x的左二子为2x,右儿子为2x+1的关系,利用down(向下移动)、up(向上移动)函数实现题目要求。
求最小值: heap[1];
插入:heap[++size] = x; up[size];
删除最小值: heap[1] = heap[size]; size–; down(1);
删除任意值:heap[k] = heap[size]; size–; down(k); up(k);
修改任意值:heap[k] = x; down(k); up(k);

程序代码:

#include <iostream>
using namespace std;

const int N = 100010;
int n, m, s, h[N];

void down(int u)
{
    int t = u;
    if(u * 2 <= s && h[u * 2] < h[t])  t = u * 2;
    if(u * 2 + 1 <= s && h[u * 2 + 1] < h[t])  t = u * 2 + 1;
    if(t != u)
    {
        swap(h[t], h[u]);
        down(t);
    }
}

void up(int u)
{
    while(u / 2 && h[u/ 2] > h[u])
    {
        swap(h[u / 2], h[u]);
        u /= 2;
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i ++)  scanf("%d", &h[i]);
    s = n;
    
    for(int i = n / 2; i ; i --)  down(i);
    
    while(m --)
    {
        printf("%d ", h[1]);
        h[1] = h[s];
        s --;
        down(1);
    }
    return 0;
}

2.模拟堆

维护一个集合,初始时集合为空,支持如下几种操作:
“I x”,插入一个数x;
“PM”,输出当前集合中的最小值;
“DM”,删除当前集合中的最小值(数据保证此时的最小值唯一);
“D k”,删除第k个插入的数;
“C k x”,修改第k个插入的数,将其变为x;
现在要进行N次操作,对于所有第2个操作,输出当前集合的最小值。

输入格式
第一行包含整数N。
接下来N行,每行包含一个操作指令,操作指令为”I x”,”PM”,”DM”,”D k”或”C k x”中的一种。

输出格式
对于每个输出指令“PM”,输出一个结果,表示当前集合中的最小值。
每个结果占一行。

数据范围
1≤N≤105
−109≤x≤109
数据保证合法。

输入样例:
8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM
输出样例:
-10
6

程序代码:

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;

const int N = 100010;
int h[N], ph[N], hp[N], s;//ph存放第k个插入点的下标, hp存放堆中点的插入次序

void heap_swap(int a, int b)
{
    swap(ph[hp[a]], ph[hp[b]]);
    swap(hp[a], hp[b]);
    swap(h[a], h[b]);
}

void down(int u)
{
    int t = u;
    if(u * 2 <= s && h[u * 2] < h[t])  t = u * 2;
    if(u * 2 + 1 <= s && h[u * 2 + 1] < h[t])  t = u * 2 + 1;
    if(u != t)
    {
        heap_swap(u, t);
        down(t);
    }
}

void up(int u)
{
    while(u / 2 && h[u / 2] > h[u])
    {
        heap_swap(u, u / 2);
        u /= 2;
    }
}

int main()
{
    int n, m = 0;
    scanf("%d", &n);
    while(n --)
    {
        char op[10];
        int k, x;
        
        scanf("%s", op);
        if(!strcmp(op, "I"))
        {
            scanf("%d", &x);
            s ++, m ++;
            ph[m] = s, hp[s] = m;
            h[s] = x;
            up(s);
        }
        else if(!strcmp(op, "PM"))  printf("%d\n", h[1]);
        else if(!strcmp(op, "DM"))
        {
            heap_swap(1, s);
            s --;
            down(1);
        }
        else if(!strcmp(op, "D"))
        {
            scanf("%d", &k);
            k = ph[k];
            heap_swap(k, s);
            s --;
            down(k), up(k);
        }
        else
        {
            scanf("%d%d", &k, &x);
            k = ph[k];
            h[k] = x;
            down(k), up(k);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
算法与数据结构它们分别涵盖了以下主要内容: 数据结构(Data Structures): 逻辑结构:描述数据元素之间的逻辑关系,如线性结构(如数组、链表)、树形结构(如二叉树、堆、B树)、图结构(有向图、无向图等)以及集合和队列等抽象数据类型。 存储结构(物理结构):描述数据在计算机中如何具体存储。例如,数组的连续存储,链表的动态分配节点,树和图的邻接矩阵或邻接表表示等。 基本操作:针对每种数据结构,定义了一系列基本的操作,包括但不限于插入、删除、查找、更新、遍历等,并分析这些操作的时间复杂度和空间复杂度。 算法: 算法设计:研究如何将解决问题的步骤形式化为一系列指令,使得计算机可以执行以求解问题。 算法特性:包括输入、输出、有穷性、确定性和可行性。即一个有效的算法必须能在有限步骤内结束,并且对于给定的输入产生唯一的确定输出。 算法分类:排序算法(如冒泡排序、快速排序、归并排序),查找算法(如顺序查找、二分查找、哈希查找),图论算法(如Dijkstra最短路径算法、Floyd-Warshall算法、Prim最小生成树算法),动态规划,贪心算法,回溯法,分支限界法等。 算法分析:通过数学方法分析算法的时间复杂度(运行时间随数据规模增长的速度)和空间复杂度(所需内存大小)来评估其效率。 学习算法与数据结构不仅有助于理解程序的内部工作原理,更能帮助开发人员编写出高效、稳定和易于维护的软件系统。
### 回答1: Python提供了一个内置的数据结构叫做堆,它可以帮助你实现堆排序,最小堆,最大堆等功能。Python的heapq模块提供了一些函数来操作堆,比如heappush(),heappop(),heapify()等等。你可以使用这些函数来模拟堆数据结构。 ### 回答2: 使用Python编程语言来模拟数据结构堆是很容易的。下面是一个简单的例子: 首先,可以创建一个名为Heap的类来实现堆的相关操作。该类有一个列表作为成员变量来存储堆中的元素。可以创建构造方法来初始化这个列表。例如: ```python class Heap: def __init__(self): self.heap = [] ``` 接下来,可以实现一些堆的基本操作,如插入元素、删除元素和获取堆的大小等。以下是一个示例: ```python class Heap: def __init__(self): self.heap = [] def insert(self, value): self.heap.append(value) self._heapify_up(len(self.heap) - 1) def delete(self, index): if len(self.heap) == 0: return self._swap(index, len(self.heap) - 1) self.heap.pop() self._heapify_down(index) def size(self): return len(self.heap) def _heapify_up(self, index): parent = (index - 1) // 2 if index > 0 and self.heap[index] < self.heap[parent]: self._swap(index, parent) self._heapify_up(parent) def _heapify_down(self, index): left_child = (2 * index) + 1 right_child = (2 * index) + 2 smallest = index if left_child < len(self.heap) and self.heap[left_child] < self.heap[smallest]: smallest = left_child if right_child < len(self.heap) and self.heap[right_child] < self.heap[smallest]: smallest = right_child if smallest != index: self._swap(index, smallest) self._heapify_down(smallest) def _swap(self, i, j): self.heap[i], self.heap[j] = self.heap[j], self.heap[i] ``` 上面的代码演示了如何使用Python模拟数据结构堆。通过创建一个Heap类,使用列表来表示堆的基本操作,如插入、删除和获取大小。还实现了一些辅助方法(以"_"为前缀),例如_heapify_up和_heapify_down来调整堆的顺序。 总之,使用Python来模拟数据结构堆是相对简单的。可以使用类和列表来实现堆的基本操作,并实现一些辅助方法来维护堆的特性。 ### 回答3: Python可以使用列表来模拟数据结构堆。堆是一个完全二叉树,其中的每个节点的键值都必须大于等于(或小于等于)其子节点的键值。下面是一个使用列表来模拟最小堆的示例: ```python class MinHeap: def __init__(self): self.heap = [] def parent(self, i): return (i-1)//2 def left_child(self, i): return 2*i + 1 def right_child(self, i): return 2*i + 2 def insert(self, k): self.heap.append(k) i = len(self.heap) - 1 while i != 0 and self.heap[self.parent(i)] > self.heap[i]: self.heap[self.parent(i)], self.heap[i] = self.heap[i], self.heap[self.parent(i)] i = self.parent(i) def extract_min(self): if len(self.heap) == 0: return None min_value = self.heap[0] self.heap[0] = self.heap.pop() self.min_heapify(0) return min_value def min_heapify(self, i): left = self.left_child(i) right = self.right_child(i) smallest = i if left < len(self.heap) and self.heap[left] < self.heap[smallest]: smallest = left if right < len(self.heap) and self.heap[right] < self.heap[smallest]: smallest = right if smallest != i: self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i] self.min_heapify(smallest) ``` 这个MinHeap类包含了一些基本的操作,包括构造函数`__init__`、找到父节点`parent`、找到左孩子节点`left_child`、找到右孩子节点`right_child`、插入一个元素`insert`、提取最小元素`extract_min`以及维持堆的性质`min_heapify`等。 这样,我们就可以使用这个MinHeap类来模拟数据结构堆了。例如,我们可以使用如下代码创建一个最小堆、插入一些元素并提取最小元素: ```python heap = MinHeap() heap.insert(3) heap.insert(2) heap.insert(1) heap.insert(4) print(heap.heap) # 输出: [1, 3, 2, 4] min_value = heap.extract_min() print(min_value) # 输出: 1 print(heap.heap) # 输出: [2, 3, 4] ``` 这段代码首先创建了一个最小堆,然后向堆中插入了一些元素,最后使用`extract_min`方法提取出最小元素并打印结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值