优先队列: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)的更多相关文章

  1. 【algo&ds】【吐血整理】4.树和二叉树、完全二叉树、满二叉树、二叉查找树、平衡二叉树、堆、哈夫曼树、B树、字典树、红黑树、跳表、散列表

    本博客内容耗时4天整理,如果需要转载,请注明出处,谢谢. 1.树 1.1树的定义 在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结 ...

  2. 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)

    树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...

  3. 哈夫曼树【最优二叉树】【Huffman】

    [转载]只为让价值共享,如有侵权敬请见谅! 一.哈夫曼树的概念和定义 什么是哈夫曼树? 让我们先举一个例子. 判定树:         在很多问题的处理过程中,需要进行大量的条件判断,这些判断结构的设 ...

  4. 6-9-哈夫曼树(HuffmanTree)-树和二叉树-第6章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第6章  树和二叉树 - 哈夫曼树(HuffmanTree) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版> ...

  5. javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

    赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支 ...

  6. 树&二叉树&哈夫曼树

    1.树 需要注意的两点:n(n>=0)表示结点的个数,m表示子树的个数 (1)n>0时,树的根节点是唯一的. (2)m>0时,子树的个数没有限制. 结点的度和树的度 (1)结点的度是 ...

  7. [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)

    一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...

  8. 数据结构-二叉树(6)哈夫曼树(Huffman树)/最优二叉树

    树的路径长度是从树根到每一个结点的路径长度(经过的边数)之和. n个结点的一般二叉树,为完全二叉树时取最小路径长度PL=0+1+1+2+2+2+2+… 带权路径长度=根结点到任意结点的路径长度*该结点 ...

  9. hdu 2527哈夫曼树(二叉树的运用)

    #include<stdio.h> #include<string.h> #define N  100 #define INF  2000000000  int b[N]; c ...

随机推荐

  1. Spring集成Swagger,Java自动生成Api文档

    博主很懒... Swagger官网:http://swagger.io GitHub地址:https://github.com/swagger-api 官方注解文档:http://docs.swagg ...

  2. HTML基础语法

    目录 HTML基础语法 1.全局架构标签 2.标题 3.段落 4.文本 5.属性 6.链接 7.图片 8.列表 9.表格 10.区块 11.布局 12.表单 13.框架 14.头部 HTML基础语法 ...

  3. HTML快速入门(一)

    一.HTML 是什么? HTML 指的是超文本标记语言 (Hyper Text Markup Language) HTML 不是一种编程语言,而是一种标记语言 (markup language) 标记 ...

  4. CSS快速入门-组合选择器

    <div class="gradefather"> hello1 <div class="father">hello2 <p cl ...

  5. Android几行代码实现监听微信聊天

    原创作品,转载请注明出处,尊重别人的劳动果实. 2017.2.7更新: *现在适配微信版本更加容易了,只需要替换一个Recourse-ID即可 *可以知道对方发的是小视频还是语音,并获取秒数. *可以 ...

  6. MOSFET简介以及PMOS和NMOS的差异

    最近在工作中,一直在调试关于MOSFET的电路.在设计过程中发现了PMOS和NMOS的差异,在此记录. 一. MOSFET简介 MOSFET (metal-oxide-semiconductor fi ...

  7. HTTP协议图--概述

    1.计算机网络体系结构分层 2.TCP/IP 通信传输流 利用 TCP/IP 协议族进行网络通信时,会通过分层顺序与对方进行通信.发送端从应用层往下走,接收端则从链路层往上走.如下:   3.TCP/ ...

  8. Linux_01

    要安装centos系统,就必须得有centos系统软件安装程序,可以通过浏览器访问centos官网http://www.centos.org,然后找到Downloads  - >  mirror ...

  9. Daily Scrumming* 2015.12.16(Day 8)

    一.团队scrum meeting照片 二.成员工作总结 姓名 任务ID 迁入记录 江昊 任务1036 https://github.com/buaaclubs-team/temp-front/com ...

  10. 一个java实现的简单的4则运算器

    有些基础知识有欠缺,补一下,顺便练习一下java import com.sun.deploy.util.ArrayUtil; import java.util.*; public class Main ...