哈夫曼树;二叉树;二叉排序树(BST)
优先队列:priority_queue<Type, Container, Functional>
Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。
Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.
STL里面默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个
参数缺省的话,优先队列就是大顶堆,队头元素最大。
而在求哈夫曼树中,我
们恰恰需要取得堆中最小的元素,于是我们使用如下语句定义一个小顶堆:
priority_queue<int , vector<int> , greater<int> > Q;
关于堆的有关操作如下:
Q.push(x);
将元素 x 放入堆 Q 中。
int a = Q.top();
取出堆顶元素,即最小的元素保存在 a 中。
Q.pop();
弹出堆顶元素,取出后堆会自动调整为一个新的小顶堆。
它的定义与之前我们使用过的队列一样在标准模板库 queue 中,所以在使用
它之前我们必须做相应预处理。
#include <queue>
30.哈夫曼树(九度)
.哈夫曼树
时间限制: 秒
内存限制: 兆
特殊判题:否
题目描述:
哈夫曼树,第一行输入一个数 n,表示叶结点的个数。需要用这些叶结点生
成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即 weight,题目需要输出
所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数 n,接着输入 n 个叶节点(叶节点权值不超过 ,
<=n<=)。
输出:
输出权值。
样例输入: 样例输出:
#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
#include <limits.h>
#include <queue>
using namespace std; priority_queue<int , vector<int> , greater<int> > Q; //建立一个小顶堆
int main () {
int n;
while (scanf ("%d",&n) != EOF) {
while(Q.empty() == false) Q.pop(); //清空堆中元素
for (int i = ;i <= n;i ++) { //输入n个叶子结点权值
int x;
scanf ("%d",&x);
Q.push(x); //将权值放入堆中
}
int ans = ; //保存答案
while(Q.size() > ) { //当堆中元素大于1个
int a = Q.top();
Q.pop();
int b = Q.top();
Q.pop(); //取出堆中两个最小元素,他们为同一个结点的左右儿子,且该双亲结点的权值为它们的和
ans += a + b; //该父亲结点必为非叶子结点,固累加其权值
Q.push(a + b); //将该双亲结点的权值放回堆中
}
printf("%d\n",ans); //输出答案
}
return ;
}
32.二叉树遍历(jiu du)
二叉树遍历(九度教程第 题)
时间限制: 秒
内存限制: 兆
特殊判题:否题目描述:
二叉树的前序、中序、后序遍历的定义:
前序遍历:对任一子树,先访问跟,然后遍历其左子树,最后遍历其右子树;
中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树;
后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
给定一棵二叉树的前序遍历和中序遍历,求其后序遍历(提示:给定前序遍
历与中序遍历能够唯一确定后序遍历)。
输入:
两个字符串,其长度 n 均小于等于 。
第一行为前序遍历,第二行为中序遍历。二叉树中的结点名称以大写字母表
示:A,B,C....最多 个结点。
输出:
输入样例可能有多组,对于每组测试样例,输出一行,为后序遍历的字符串。
样例输入:
ABC
BAC
FDXEAG
XDEFAG
样例输出:
BCA
XEDGAF
Problem
#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
#include <limits.h>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;
struct Node { //树结点结构体
Node *lchild; //左儿子指针
Node *rchild; //右儿子指针
char c; //结点字符信息
}Tree[]; //静态内存分配数组
int loc; //静态数组中已经分配的结点个数
Node *creat() { //申请一个结点空间,返回指向其的指针
Tree[loc].lchild = Tree[loc].rchild = NULL; cout << loc << ' ';//初始化左右儿子为空
return &Tree[loc ++]; //返回指针,且loc累加
}
char str1[] , str2[]; //保存前序和中序遍历结果字符串
void postOrder(Node *T) { //后序遍历
if (T -> lchild != NULL) { //若左子树不为空
postOrder(T -> lchild); //递归遍历其左子树
}
if (T -> rchild != NULL) { //若右子树不为空
postOrder(T -> rchild); //递归遍历其右子树
}
printf("%c",T -> c); //遍历该结点,输出其字符信息
}
Node *build(int s1,int e1,int s2,int e2) { //由字符串的前序遍历和中序遍历还原树,并返回其根节点,其中前序遍历结果为由str1[s1]到str1[e1],中序遍历结果为str2[s2]到str2[e2]
Node* ret = creat(); //为该树根节点申请空间
ret -> c = str1[s1]; //该结点字符为前序遍历中第一个字符
int rootIdx;
for (int i = s2;i <= e2;i ++) {//查找该根节点字符在中序遍历中的位置
if (str2[i] == str1[s1]) {
rootIdx = i;
break;
}
}
if (rootIdx != s2) { //若左子树不为空
ret -> lchild = build(s1 + ,s1 + (rootIdx - s2),s2,rootIdx - ); //递归还原其左子树
}
if (rootIdx != e2) { //若右子树不为空
ret -> rchild = build(s1 + (rootIdx - s2) + ,e1,rootIdx + ,e2); //递归还原其右子树
}
return ret; //返回根节点指针
}
int main () {
while (scanf ("%s",str1) != EOF) {
scanf ("%s",str2); //输入
loc = ; //初始化静态内存空间中已经使用结点个数为0
int L1 = strlen(str1);
int L2 = strlen(str2); //计算两个字符串长度
Node *T = build(,L1 - ,,L2 - ); //还原整棵树,其根结点指针保存在T中
postOrder(T); //后序遍历
printf("\n"); //输出换行
}
return ;
}
35.二叉排序树 (Binary Search Tree),(又:二叉搜索树,二叉查找树)
由于各个数字插入的顺序不同,所得到的二叉排序树的形态也很可能不同,
所以不同的插入顺序对二叉排序树的形态有重要的影响。但是,所有的二叉排序
树都有一个共同的特点:若对二叉排序树进行中序遍历,那么其遍历结果必然是
一个递增序列,这也是二叉排序树名字的来由,通过建立二叉排序树就能对原无
序序列进行排序,并实现动态维护。
例 3.5 二叉排序树 (九度教程第 题)
时间限制: 秒
内存限制: 兆
特殊判题:否
题目描述:
输入一系列整数,建立二叉排序数,并进行前序,中序,后序遍历。
输入:
输入第一行包括一个整数 n(<=n<=)。接下来的一行包括 n 个整数。
输出:
可能有多组测试数据,对于每组数据,将题目所给数据建立一个二叉排序树,
并对二叉排序树进行前序、中序和后序遍历。每种遍历结果输出一行。每行最后
一个数据之后有一个空格。
样例输入: 样例输出: 提示:
输入中可能有重复元素,但是输出的二叉树遍历序列中重复元素不用输出。
problem
#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
#include <limits.h>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std;
struct Node { //二叉树结构体
Node *lchild; //左儿子指针
Node *rchild; //右儿子指针
int c;//保存数字
}Tree[]; //静态数组
int loc; //静态数组中被使用元素个数
Node *creat() { //申请未使用的结点
Tree[loc].lchild = Tree[loc].rchild = NULL;
return &Tree[loc ++];
}
void postOrder(Node *T) { //后序遍历
if (T -> lchild != NULL) {
postOrder(T -> lchild);
}
if (T -> rchild != NULL) {
postOrder(T -> rchild);
}
printf("%d ",T -> c);
}
void inOrder(Node *T) { //中序遍历
if (T -> lchild != NULL) {
inOrder(T -> lchild);
}
printf("%d ",T -> c);
if (T -> rchild != NULL) {
inOrder(T -> rchild);
}
}
void preOrder(Node *T) { //前序遍历
printf("%d ",T -> c);
if (T -> lchild != NULL) {
preOrder(T -> lchild);
}
if (T -> rchild != NULL) {
preOrder(T -> rchild);
}
}
Node *Insert(Node *T,int x) { //插入数字
if (T == NULL) { //若当前树为空
T = creat(); //建立结点
T -> c = x; //数字直接插入其根结点
return T; //返回根结点指针
}
else if (x < T->c) //若x小于根结点数值
T -> lchild = Insert(T -> lchild,x); //插入到左子树上
else if (x > T->c) //若x大于根结点数值
T -> rchild = Insert(T -> rchild,x); //插入到右子树上.若根结点数值与x一样,根据题目要求直接忽略
return T; //返回根节点指针
}
int main () {
int n;
while (scanf ("%d",&n) != EOF) {
loc = ;
Node *T = NULL; //二叉排序树树根结点为空
for (int i = ;i < n;i ++) { //依次输入n个数字
int x;
scanf ("%d",&x);
T = Insert(T,x); //插入到排序树中
}
preOrder(T); //前序遍历
printf("\n"); //输出空行
inOrder(T); //中序遍历
printf("\n");
postOrder(T); //后序遍历
printf("\n");
}
return ;
}
例 3.6 二叉搜索树(九度教程第 题)
时间限制: 秒
内存限制: 兆
特殊判题:否
题目描述:
判断两序列是否为同一二叉搜索树序列
输入:
开始一个数 n,(<=n<=) 表示有 n 个需要判断,n= 的时候输入结束。
接下去一行是一个序列,序列长度小于 ,包含(~)的数字,没有重复数字,
根据这个序列可以构造出一颗二叉搜索树。
接下去的 n 行有 n 个序列,每个序列格式跟第一个序列一样,请判断这两个
序列是否能组成同一颗二叉搜索树。
输出:
如果序列相同则输出 YES,否则输出 NO
样例输入: 样例输出:
YES
NO
problem
#include <algorithm>
#include <functional>
#include <array>
#include <iostream>
#include <limits.h>
#include <queue>
#include <stdio.h>
#include <string.h>
using namespace std; struct Node { //树节点结构体
Node *lchild;
Node *rchild;
int c;
}Tree[];
int loc;
Node *creat() { //申请结点空间
Tree[loc].lchild = Tree[loc].rchild = NULL;
return &Tree[loc ++];
}
char str1[] , str2[]; //保存二叉排序树的遍历结果,将每一棵树的前序遍历得到的字符串与中序遍历得到的字符串连接,得到遍历结果字符串
int size1 , size2; //保存在字符数组中的遍历得到字符个数
char *str; //当前正在保存字符串
int *size; //当前正在保存字符串中字符个数
void postOrder(Node *T) { //前序遍历
if (T -> lchild != NULL) {
postOrder(T -> lchild);
}
if (T -> rchild != NULL) {
postOrder(T -> rchild);
}
str[ (*size) ++ ] = T -> c + ''; //将结点中的字符放入正在保存的字符串中
}
void inOrder(Node *T) { //中序遍历
if (T -> lchild != NULL) {
inOrder(T -> lchild);
}
str[ (*size) ++ ] = T -> c + '';
if (T -> rchild != NULL) {
inOrder(T -> rchild);
}
}
Node *Insert(Node *T,int x) { //将数字插入二叉树
if (T == NULL) {
T = creat();
T -> c = x;
return T;
}
else if (x < T->c)
T -> lchild = Insert(T -> lchild,x);
else if (x > T->c)
T -> rchild = Insert(T -> rchild,x);
return T;
}
int main () {
int n;
char tmp[];
while (scanf ("%d",&n) != EOF && n != ) {
loc = ; //初始化静态空间为未使用
Node *T = NULL;
scanf ("%s",tmp); //输入字符串
for (int i = ;tmp[i] != ;i ++) {
T = Insert(T,tmp[i] - ''); //按顺序将数字插入二叉排序树
}
size1 = ; //保存在第一个字符串中的字符初始化为0
str = str1; //将正在保存字符串设定为第一个字符串
size = &size1; //将正在保存字符串中的字符个数指针指向size1
postOrder(T); //前序遍历
inOrder(T); //中序遍历
str1[ size1 ] = ; //向第一个字符串的最后一个字符后添加空字符,方便使用字符串函数
while(n -- != ) { //输入n个其它字符串
scanf ("%s",tmp); //输入
Node *T2 = NULL;
for (int i = ;tmp[i] != ;i ++) { //建立二叉排序树
T2 = Insert(T2,tmp[i] - '');
}
size2 = ; //第二个字符串保存字符初始化为0
str = str2; //将正在保存字符串设定为第二个字符串
size = &size2; //正在保存字符串中字符数量指针指向size2
postOrder(T2); //前序遍历
inOrder(T2); //中序遍历
str2[ size2 ] = ; //字符串最后添加空字符
puts (strcmp(str1,str2) == ? "YES" : "NO"); //比较两个遍历字符串,若相同则输出YES,否则输出NO
}
}
return ;
}
哈夫曼树;二叉树;二叉排序树(BST)的更多相关文章
- 【algo&ds】【吐血整理】4.树和二叉树、完全二叉树、满二叉树、二叉查找树、平衡二叉树、堆、哈夫曼树、B树、字典树、红黑树、跳表、散列表
本博客内容耗时4天整理,如果需要转载,请注明出处,谢谢. 1.树 1.1树的定义 在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结 ...
- 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)
树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...
- 哈夫曼树【最优二叉树】【Huffman】
[转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树: 在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...
- 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版
课本源码部分 第6章 树和二叉树 - 哈夫曼树(HuffmanTree) ——<数据结构>-严蔚敏.吴伟民版 源码使用说明 链接☛☛☛ <数据结构-C语言版> ...
- javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题
赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...
- 树&二叉树&哈夫曼树
1.树 需要注意的两点:n(n>=0)表示结点的个数,m表示子树的个数 (1)n>0时,树的根节点是唯一的. (2)m>0时,子树的个数没有限制. 结点的度和树的度 (1)结点的度是 ...
- [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)
一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...
- 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树
树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...
- hdu 2527哈夫曼树(二叉树的运用)
#include<stdio.h> #include<string.h> #define N 100 #define INF 2000000000 int b[N]; c ...
随机推荐
- WPF解决按钮上被透明控件遮盖时无法点击问题
原文:WPF解决按钮上被透明控件遮盖时无法点击问题 IsHitTestVisible="False" 在控件上设置如上属性即可,即可让透明控件不触发点击效果
- MFC如何为程序添加图标
1.找几幅Ico格式的图片,可以在电脑中查找.ico一般都会找到.然后将ico文件放在工程目录下的res文件夹下. 2.点击菜单栏->编辑->添加资源->导入,选择res文件夹中将要 ...
- 分享一下个人学PS的过程
得知Photoshop这款软件是在上大学的时候,2010年.学校学生会的科技部纳新,要求新人会PPT.word.Excel和Photoshop.当时有一个Photoshop大神,成为了学生会科技部的主 ...
- ElasticSearch查询 第三篇:词条查询
<ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...
- 一个Python开源项目-腾讯哈勃沙箱源码剖析(上)
前言 2019年来了,2020年还会远吗? 请把下一年的年终奖发一下,谢谢... 回顾逝去的2018年,最大的改变是从一名学生变成了一位工作者,不敢说自己多么的职业化,但是正在努力往那个方向走. 以前 ...
- Azkaban集群部署
一.部署模式 solo-server模式 (使用内置h2存储元数据): two-server模式 (1个webServer,1个execServer在同一服务器上,使用mysql存储元数据): mu ...
- LintCode——筛子求和
描述:扔n个骰子,向上面的数字之和为 S .给定 Given n,请列出所有可能的 S 值及其相应的概率. 样例:给定n=1,返回 [ [1, 0.17], [2, 0.17], [3, 0.17], ...
- 利用Python实现App自动签到领取积分
要自动签到,最简单的是打开页面分析请求,然后我们用脚本实现请求的自动化.但是发现食行没有页面,只有 APP,这不是一个好消息,这意味着需要抓包处理了. 有需要Python学习资料的小伙伴吗?小编整理[ ...
- PAT甲题题解-1022. Digital Library (30)-map映射+vector
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/6789235.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- 11.7 Daily Scrum(周末暂停两天Daily Scrum)
由于APEC放假,有些成员离校了,他们那部分的任务会暂时拖后一些,之后会加班加点赶工. 另外,每个人的任务还是相对独立,离校成员的任务进度不会对其他成员的进度造成很大影响. Today's tas ...