当前位置: 首页 > news >正文

数据结构 | 构造哈夫曼树

template<class T>
void Heap<T>::PercolateUp() //为了向上调整为堆,我们需要比较当前节点和其父节点的值,如果父节点的值比当前节点大,则交换它们的值。
{

    int p = size - 1, c = (p - 1) / 2;//`c`表示当前节点的父节点,`p`表示当前节点。
    T temp = vec[p];
    while (p > 0) //为什么不是c>0
        

        //在`while`循环中,我们判断当前节点是否已经到达根节点,如果是根节点则停止循环。所以条件应该是`p > 0`,而不是`c > 0`。

        
    {
        if (vec[c] <= temp)
            break;
        else
        {
            vec[p] = vec[c];
            p = c;
            c = (p - 1) / 2;
        }
    }
    vec[p] = temp; //写在while 里面还是外面目前结点最后会空出来
}

 


template<class T>
void Heap<T>::PercolateDown(int h)// 向下调整为堆,如果父亲节点(目前结点)比孩子结点(较小值)大交换
{
    int p = h, c = 2 * p + 1;// c为p的左孩子
    T temp = vec[h]; //不定类型  不用写成int
    while (c < size)  //怎么修改?
    {
        if (c + 1 < size && vec[c + 1] < vec[c]) //左孩子的下标小于size-1(最后一个叶子结点)&&找到左右孩子的最小值

//c < size表示当前节点有左孩子,而c + 1 < size表示当前节点有右孩子。根据堆的性质,选择较小的孩子进行交换。

        {
            ++c;
        }
        if (temp <= vec[c])
            break;
        else
        {
            vec[p] = vec[c];
            p = c;
            c = 2 * p + 1;
        }
    }
    vec[p] = temp;


#include<iostream>
#include<vector> 
#include<queue>
using namespace std;template<class T>
struct BTNode
{T data;BTNode* left, * right;BTNode(const T& item = T(), BTNode* lptr = NULL, BTNode* rptr = NULL) :data(item), left(lptr), right(rptr) {}
};void Gotoxy(int x, int y)
{static int level = 0, indent = 0;if (y == 0){indent = 0;level = 0;}if (level != y){cout << endl;indent = 0;level++;}cout.width(x - indent);indent = x;
}template<class T>
BTNode<T>* GetBTNode(const T& item, BTNode<T>* lp = NULL, BTNode<T>* rp = NULL)
{BTNode<T>* p;p = new BTNode<T>(item, lp, rp);if (p == NULL){cout << "error!" << endl;}return p;
}struct Location
{int xindent, ylevel;
};template<class T>
void PrintBTree(const BTNode<T>* t, int screenwidth)
{if (t == NULL){return;}int level = 0, offset = screenwidth / 2;Location floc, cloc;queue<const BTNode<T>*> Q;queue<Location> LQ;floc.xindent = offset;floc.ylevel = level;Q.push(t);LQ.push(floc);while (!Q.empty()){t = Q.front();floc = LQ.front();Q.pop();LQ.pop();Gotoxy(floc.xindent, floc.ylevel);cout << t->data;if (floc.ylevel != level){level++;offset = offset / 2;}if (t->left){Q.push(t->left);cloc.ylevel = floc.ylevel + 1;cloc.xindent = floc.xindent - offset / 2;LQ.push(cloc);}if (t->right){Q.push(t->right);cloc.ylevel = floc.ylevel + 1;cloc.xindent = floc.xindent + offset / 2;LQ.push(cloc);}}cout << endl;}template<class T>
class Heap   //小根堆 根->叶子 小到大
{vector<T> vec;int size;void BuildHeap(void);void PercolateUp();void PercolateDown(int h);
public:Heap(int max = 100) : vec(max), size(0) {}Heap(const vector<T>& vt);int Size(){return size;}void Insert(const T& item);void DeleteMin(void);void DeleteMin(T& item);
};template<class T>
void Heap<T>::PercolateUp() //为了向上调整为堆,我们需要比较当前节点和其父节点的值,如果父节点的值比当前节点大,则交换它们的值。
{int p = size - 1, c = (p - 1) / 2;//`c`表示当前节点的父节点,`p`表示当前节点。T temp = vec[p];while (p > 0) //为什么不是c>0//在`while`循环中,我们判断当前节点是否已经到达根节点,如果是根节点则停止循环。所以条件应该是`p > 0`,而不是`c > 0`。{if (vec[c] <= temp)break;else{vec[p] = vec[c];p = c;c = (p - 1) / 2;}}vec[p] = temp; //写在while 里面还是外面? 目前结点最后会空出来
}template<class T>
void Heap<T>::PercolateDown(int h)// 向下调整为堆,如果父亲节点(目前结点)比孩子结点(较小值)大交换
{int p = h, c = 2 * p + 1;// c为p的左孩子T temp = vec[h];while (c < size)  //怎么修改?{if (c + 1 < size && vec[c + 1] < vec[c]) //左孩子的下标小于size-1(最后一个叶子结点)&&找到左右孩子的最小值{++c;}if (temp <= vec[c])break;else{vec[p] = vec[c];p = c;c = 2 * p + 1;}}vec[p] = temp;
}template<class T>
void Heap<T>::Insert(const T& item)
{if (size == vec.size()){vec.resize(vec.size() *2);}vec[size] = item;size++;PercolateUp();}template<class T>
void Heap<T>::BuildHeap(void) //从最后一个非叶子结点(a)开始,size-1是最后一个叶子结点,a是它的parent
{for (int i = size / 2 - 1; i >= 0; i--){PercolateDown(i);//为该结点的子树调整成堆}
}template<class T>
void Heap<T>::DeleteMin()
{if (size == 0){return;}vec[0] = vec[size - 1];size--;PercolateDown(0);
}template<class T>
void Heap<T>::DeleteMin(T& item)
{if (size == 0) //删除最小值需要判断堆是否为空{return;}item = vec[0];vec[0] = vec[size - 1];size--;PercolateDown(0);
}template<class T>
Heap<T>::Heap(const vector<T>& vt) : vec(vt.size() + 10), size(vt.size())
{for (int i = 0; i < size; i++){vec[i] = vt[i];}BuildHeap();
}template<class T>
struct HuffmanNode
{BTNode<T>* t;int operator<(const HuffmanNode& h)//穿入参数是哈夫曼节点 bool类型{return (t->data < h.t->data);}int operator<=(const HuffmanNode& h)//穿入参数是哈夫曼节点{return (t->data <= h.t->data);}
};template<class T>
BTNode<T>* MakeHuffman(T* pa, int n)
{BTNode<T>* t, * right, * left;HuffmanNode<T> hf;Heap<HuffmanNode<T>> HF(n);//第一个循环将数组里的元素插入到哈夫曼堆for (int i = 0; i < n; i++){t = GetBTNode<int>(pa[i]);hf.t = t;HF.Insert(hf);}//第二个循环找到最小的两个数,生成根节点后删除for (int i = 1; i < n; i++){HF.DeleteMin(hf);left = hf.t;HF.DeleteMin(hf);right = hf.t;t = GetBTNode(left->data + right->data, left, right);//t的左孩子是left,右孩子是righthf.t = t;HF.Insert(hf);}HF.DeleteMin(hf);//是一个对象调用函数t = hf.t;return t;
};int main()
{int a[] = { 7,5,2,4 };BTNode<int>* root;root = MakeHuffman(a, 4);PrintBTree(root, 40);cout << endl;return 0;
}

相关文章:

数据结构 | 构造哈夫曼树

template<class T> void Heap<T>::PercolateUp() //为了向上调整为堆&#xff0c;我们需要比较当前节点和其父节点的值&#xff0c;如果父节点的值比当前节点大&#xff0c;则交换它们的值。 { int p size - 1, c (p - 1) / 2;//c表示当前节点的父节点&#xff0…...

实验室烧杯可以用超声波清洗机吗

实验室烧杯可以用超声波清洗机吗&#xff1f;答案是可以的&#xff01;超声波清洗机不仅可以清洗实验烧杯&#xff0c;还可以用于清洗实验室中的试管、培养皿、移液管、载玻片、容量瓶、锥形瓶等各类实验器皿。在实验中&#xff0c;如果烧杯清洁不到位&#xff0c;会使得实验数…...

Unity之ShaderGraph如何实现UV抖动

前言 今天我们通过噪波图来实现一个UV抖动的效果。 如下图所示&#xff1a; 关键节点 Time&#xff1a;提供对着色器中各种时间参数的访问 UV&#xff1a;提供对网格顶点或片段的UV坐标的访问。可以使用通道下拉参数选择输出值的坐标通道。 SimpleNoise&#xff1a;根据…...

#力扣:771. 宝石与石头@FDDLC

771. 宝石与石头 - 力扣&#xff08;LeetCode&#xff09; 一、Java class Solution {public int numJewelsInStones(String jewels, String stones) {int[] isJewel new int[z 1];for (int i jewels.length() - 1; i > 0; i--) isJewel[jewels.charAt(i)] 1;int cnt …...

【网络协议】聊聊拓扑网络结构与原理

拓扑结构 上一篇我们简单讲述了一种交换机的情况&#xff0c;但是实际的场景是比较复杂的&#xff0c;在一个楼层可能有几十或者上百个接口&#xff0c;那么当知道对方的IP地址&#xff0c;求对方的MAC地址&#xff0c;其实是通过ARP协议进行处理的。 上图是一个两个交换机的…...

uview表单 hooks

在UViewUI库中&#xff0c;使用hooks封装表单二次可以让我们以更灵活的方式使用表单组件。下面是一个示例&#xff0c;展示如何将表单封装成hooks&#xff0c;并以JSON形式传递参数&#xff1a; 首先&#xff0c;我们可以创建一个自定义的Hook来处理表单逻辑。在这个例子中&…...

车载视频如何转换视频格式

当你收集了多种视频想在车内进行播放&#xff0c;它们可能不会自动播放。你有可能会在屏幕上看到一条消息&#xff0c;显示“文件格式不受支持”&#xff0c;这是因为这些视频可能采用了你的汽车无法识别的格式。 那我们如何才可以转换为车载播放器上运行的最重要且最广泛使用…...

虚拟音频设备软件 Loopback mac中文版软件介绍

创建虚拟音频设备以从应用程序和音频输入设备获取声音&#xff0c;然后将其发送到音频处理应用程序&#xff0c;它就是—Loopback for Mac&#xff0c;Loopback mac为您提供高端工作室混音板的强大功能&#xff0c;有了它在Mac上传递音频会变得很容易。 Loopback for mac中文版…...

Android SurfaceControlViewHost介绍及使用

概要介绍 SurfaceControlViewHost是一个工具类&#xff0c; 用于帮助在其他进程中显示本进程的view。 SurfaceControlViewHost 为绘制进程持有&#xff0c;其中的SurfacePackage 交给另外的显示进程&#xff0c;在显示进程中的SurfaceView中通过SurfaceView.setChildSurface…...

微信小程序开发(一)

目录 开发者界面 app.json配置(举例) 组件 样式 像素 flex布局 微信小程序是一种基于微信平台的应用程序开发模式&#xff0c;它可以让开发者使用前端开发技术&#xff08;如HTML、CSS和JavaScript&#xff09;开发应用程序&#xff0c;并在微信客户端中运行。以下是微信…...

MySQL数据库操作(创建、修改、删除、查询)

MySQL查看或显示数据库&#xff08;SHOW DATABASES语句&#xff09; 在 MySQL 中&#xff0c;可使用 SHOW DATABASES 语句来查看或显示当前用户权限范围以内的数据库。查看数据库的语法格式为&#xff1a; SHOW DATABASES [LIKE ‘数据库名’]; 语法说明如下&#xff1a; 语法…...

【合宙Air700E/780E短信转发】短信转发移动联通 不要钉钉不要微信,转发自建服务器-傻瓜式搭建

官方提供的教程介绍了通过钉钉、微信等工具接收短信验证码的方法&#xff0c;但最终实现的目的是获取验证码&#xff0c;而不是通过工具间接获得。 因此&#xff0c;我们可以直接调用API接口来获取验证码&#xff0c;从而达到更快、更便捷地获得验证码的目的。 所以做了一个服…...

TStor CSP文件存储在大模型训练中的实践

业务背景 大模型作为人工智能领域的重要发展趋势&#xff0c;正在逐渐改变人们的生活和工作方式。随着近年来大模型领域技术的突破&#xff0c;各类语言模型、图像模型、视频模型快速演进&#xff0c;国内外市场也不断涌现出优秀的大模型研究及商业化平台&#xff0c;预期通过…...

最用的几个git命令

1、git init​ 用于初始化一个新的Git仓库。 执行这个命令后&#xff0c;Git会在当前目录下创建一个名为".git"的子目录&#xff0c;其中存储着仓库的所有元数据。 2、git clone​ 用于克隆一个已存在的仓库。 执行这个命令后&#xff0c;将在本地创建仓库的一个副…...

邮件网关CAC2.0防御并行:提升高校师生邮箱账号的全面安全

客户背景 解民生之多艰&#xff0c;育天下之英才。中国农业大学&#xff08;以下简称“中国农大”&#xff09;作为教育部直属高校&#xff0c;先后进入国家“211工程”和“985工程”重点建设的高水平研究型大学&#xff0c;首批入选一流大学建设高校&#xff08;A类&#xff…...

潮玩IP助力环境保护,泡泡玛特发布行业首款碳中和产品

在今年的2023上海PTS国际潮流玩具展上&#xff0c;泡泡玛特正式发布了首款“碳中和”潮玩产品DIMOO X蒙新河狸手办&#xff08;下简称DIMOO河狸&#xff09;&#xff0c;通过环保主题与流行文化的联合&#xff0c;让年轻人知道野生动物保护有多种方式&#xff0c;同时以创新的设…...

pytorch分布式数据训练结合学习率周期及混合精度

文章目录 1、SPAWN方式2、torchrun 方式 正如标题所写&#xff0c;我们正常的普通训练都是单机单卡或单机多卡。而往往一个高精度的模型需要训练时间很长&#xff0c;所以DDP分布式数据并行和混合精度可以加速模型训练。混精可以增大batch size. 如下提供示例代码&#xff0c;经…...

Looper分析

Looper分析 在 Handler 机制中&#xff0c;Looper 的作用是提供了一个消息循环 ( message loop ) 的机制&#xff0c;用于处理和分发消息。 Looper 是一个线程局部的对象&#xff0c;每个线程只能有一个 Looper 对象。它通过一个无限循环来不断地从消息队列中取出消息&#x…...

LoongArch单机Ceph Bcache加速4K随机写性能测试

LoongArch单机Ceph Bcache加速4K随机写性能测试 两块HDD做OSD [rootceph01 ~]# fio -direct1 -iodepth128 -thread -rwrandwrite -ioenginelibaio -bs4k -size100G -numjobs1 -runtime600 -group_reporting -namemytest -filename/dev/rbd0 mytest: (g0): rwrandwrite, bs(R)…...

景联文科技语音数据标注:AUTO-AVSR模型和数据助力视听语音识别

ASR、VSR和AV-ASR的性能提高很大程度上归功于更大的模型和训练数据集的使用。 更大的模型具有更多的参数和更强大的表示能力&#xff0c;能够捕获到更多的语言特征和上下文信息&#xff0c;从而提高识别准确性&#xff1b;更大的训练集也能带来更好的性能&#xff0c;更多的数据…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

动态 Web 开发技术入门篇

一、HTTP 协议核心 1.1 HTTP 基础 协议全称 &#xff1a;HyperText Transfer Protocol&#xff08;超文本传输协议&#xff09; 默认端口 &#xff1a;HTTP 使用 80 端口&#xff0c;HTTPS 使用 443 端口。 请求方法 &#xff1a; GET &#xff1a;用于获取资源&#xff0c;…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

Docker拉取MySQL后数据库连接失败的解决方案

在使用Docker部署MySQL时&#xff0c;拉取并启动容器后&#xff0c;有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致&#xff0c;包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因&#xff0c;并提供解决方案。 一、确认MySQL容器的运行状态 …...