纪念我逝去的n个小时
纪念我逝去的n个小时
某人的惨案要我擦屁股=。=
#include <bits/stdc++.h>
using namespace std;
template<class T>
struct Node {
T data;
Node<T> *Left, *Right;
Node(const T &val, Node<T> *Lptr = nullptr, Node<T> *Rptr = nullptr) :data(val), Left(Lptr), Right(Rptr) {}
};
template<class T>
class BiTree {
Node<T> *root;
int len;
public:
BiTree() :root(nullptr), len(0) {}
BiTree(const T &val) :root(new Node<T>(val)), len(1) {}
~BiTree() {
clear();
}
void clear_dfs(Node<T> *p) {
if (!p) return;//注意跳出
clear_dfs(p->Left);
clear_dfs(p->Right);
delete p;
len--;
}
void clear() {
clear_dfs(root);
root = nullptr;//不能忘
}
void Revolute_dfs(Node<T> *p) {
if (!p) return;
Revolute_dfs(p->Left);
Revolute_dfs(p->Right);
Node<T> *tmp = p->Left;
p->Left = p->Right;
p->Right = tmp;
}
void Revolute() {
Revolute_dfs(root);
}
int size()const {
return len;
}
bool empty()const {
return !len;
}
void Leefsize_dfs(Node<T> *p, int &cnt)const {
if (!p) return;
Leefsize_dfs(p->Left, cnt);
Leefsize_dfs(p->Right, cnt);
if (!p->Left && !p->Right) {
cnt++;
return;
}
}
int Leefsize()const {
int cnt = 0;
Leefsize_dfs(root, cnt);
return cnt;
}
Node<T> *find_dfs(Node<T> *p, const T &val)const {
if (!p) return nullptr;
if (p->data == val) return p;
Node<T> *tmp = nullptr;
if (tmp = find_dfs(p->Left, val)) return tmp;
if (tmp = find_dfs(p->Right, val)) return tmp;
return nullptr;
}
Node<T> *find(const T &val)const {
return find_dfs(root, val);
}
void Depth_dfs(Node<T> *p, int &dmax, int d = 1)const {
if (!p) return;
dmax = max(dmax, d);
Depth_dfs(p->Left, dmax, d + 1);
Depth_dfs(p->Right, dmax, d + 1);
}
int Depth()const {
int dmax = 0;
Depth_dfs(root, dmax);
return dmax;
}
int Depth(const T &val)const {
int dmax = 0;
Depth_dfs(find(val), dmax);
return dmax;
}
Node<T> *Create_dfs(vector<T> &v, T &fin, int &n) {//必须引用不然没法累加
clear();
T val = v[n++];
if (val == fin)
return nullptr;
else {
Node<T> *left = Create_dfs(v, fin, n);
Node<T> *right = Create_dfs(v, fin, n);
Node<T> *p = new Node<T>(val, left, right);
len++;
return p;//记得返回
}
}
void Create(vector<T> &v, T &fin, int n = 0) {//设另外个函数把root接上
root = Create_dfs(v, fin, n);
}
void Create_bfs(vector<T> &v, T &fin)//n为节点数目,root必须加引用,否则函数内的一切操作白搭
{
int i = 0;//a用作输入节点数据,i记录已经加入树中的节点个数(可以不用i,但有时候需要补很多0)
queue<Node<T> *> q;//用于按层输入数据,库函数,随便搜一搜就知道queue怎么用了
root = new Node<T>(v[i++]);//申请根节点
q.push(root);//入队
if (i == v.size()) return;
while (!q.empty()) {
Node<T> *tmp = q.front();//一轮循环为root,以后的循环为temp->R或temp->L;
q.pop();//出队
if (v[i] == fin) {
tmp->Left = NULL;
i++;
}
else {
tmp->Left = new Node<T>(v[i]);//一轮循环为将root指针的左孩子指向一个新节点,向新节点赋值刚输入的数据,并将新节点的左右孩子置NULL
q.push(tmp->Left);
i++;
}
if (i == v.size()) return;
if (v[i] == fin) {
tmp->Right = NULL;
i++;
}
else {
tmp->Right = new Node<T>(v[i]);
q.push(tmp->Right);
i++;
}
if (i == v.size()) return;
}
}
void Traverse_dfs(Node<T> *p, vector<T> &v, int mode = 0)const {
if (!p) return;//递归注意跳出
if (mode == 0) v.push_back(p->data);
Traverse_dfs(p->Left, v, mode);
if (mode == 1) v.push_back(p->data);
Traverse_dfs(p->Right, v, mode);
if (mode == 2) v.push_back(p->data);
}
void Traverse_fo_uc(Node<T> *p, vector<T> &v)const {
stack<Node<T> *> s;
Node<T> *ptr = p;///先判断节点,在入栈,可以在出栈把根节点pop,防止死循环,如果先入栈就会麻烦
while (ptr || !s.empty()) {
if (ptr) {//遍历左树节点
s.push(ptr);
v.push_back(ptr->data);
ptr = ptr->Left;
}
else {//转移到右树
Node<T> *q = s.top();
s.pop();//踢掉根节点
ptr = q->Right;
}
}
}
void Traverse_io_uc(Node<T> *p, vector<T> &v)const {///基本和上面一样
stack<Node<T> *> s;
Node<T> *ptr = p;
while (ptr || !s.empty()) {
if (ptr) {//遍历左树节点
s.push(ptr);
ptr = ptr->Left;
}
else {//转移到右树
Node<T> *q = s.top();
s.pop();//踢掉根节点
v.push_back(q->data);
ptr = q->Right;
}
}
}
void Traverse_po_uc(Node<T> *p, vector<T> &v)const {
stack<Node<T> *> s;
if (p) s.push(p);
Node<T> *last = nullptr;
while (!s.empty()) {
Node<T> *ptr = s.top();
if (!ptr->Left && !ptr->Right || last && last == ptr->Left && !ptr->Right || last && last == ptr->Right) {///叶节点||有左孩子&&上次访问左孩子&&无右孩子||有右孩子&&访问了右孩子
v.push_back(ptr->data);
last = ptr;
s.pop();
}
else {
if (ptr->Right) s.push(ptr->Right);
if (ptr->Left) s.push(ptr->Left);
}
}
}
void Traverse_bfs(Node<T> *p, vector<T> &v)const {
queue<Node<T> *> q;
q.push(p);
while (!q.empty()) {
v.push_back(q.front()->data);
if (q.front()->Left) q.push(q.front()->Left);
if (q.front()->Right) q.push(q.front()->Right);
q.pop();
}
}
void Traverse(vector<T> &v, int mode = 0)const {
if (mode <= 2) Traverse_dfs(root, v, mode);
else if (mode == 3) Traverse_fo_uc(root, v);
else if (mode == 4) Traverse_io_uc(root, v);
else if (mode == 5) Traverse_po_uc(root, v);
else if (mode == 6) Traverse_bfs(root, v);
}
void write(int mode = 0)const {
vector<T> v;
Traverse(v, mode);
for (int i = 0;i < v.size();i++) {
cout << v[i] << (i == v.size() - 1 ? "" : ",");
}
cout << endl;
}
bool isValidBST() {
return isValidBST_dfs(root);
}
bool isValidBST_dfs(Node<T> *p) {
if (!p) return true;
if (p->Left && p->data < p->Left->data) return false;
if (p->Right && p->data > p->Right->data) return false;
return isValidBST_dfs(p->Left) && isValidBST_dfs(p->Right);
}
};
int main() {
stringstream ss;
string str;
getline(cin, str);
ss.str(str);
string fin;
ss >> fin;
ss.str("");
ss.clear();
getline(cin, str);
ss.str(str);
string tmp;
vector<string> v;
while (ss >> tmp, v.push_back(tmp), tmp = fin, ss.get() == ' ');
ss.str("");
ss.clear();
BiTree<string> tree;
tree.Create_bfs(v, fin);
tree.write(1);
if (tree.isValidBST())
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
/**
!!递归部分没法内置初值,所以要引用外壳函数的变量
节点
数据
左指针,右指针
构造(值,左指针,右指针)
二叉树
根节点指针
长度
构造:无根节点
构造(值):有根节点
析构:销毁
clear_dfs(节点指针):clear的内置递归
clear:清空树,外壳
Revolute_dfs(节点指针):Revolute的内置递归
Revolute:置换所有左右子树,外壳
size:返回节点总数
Leefsize_dfs(节点指针,计数器):Leefsize的内置递归
Leefsize:返回叶节点总数,外壳
empty:返回是否为空
find_dfs(节点指针,值):find的内置递归
find(值):查找此值的节点地址
Depth_dfs(节点指针,最大值容器,计数器):Depth的内置递归
Depth:返回树深度
Depth(值):返回指定值作为根节点的树深度
Create_dfs(vector序列,结束符,计数器):返回父节点,Create的内置递归
Create(vector序列,结束符,计数器):创建树,外壳
Traverse_dfs(节点指针,vector容器,模式):Traverse的内置递归
Traverse_fo_uc(节点指针,vector容器):Traverse的内置非递归前序
Traverse_io_uc(节点指针,vector容器):Traverse的内置非递归中序
Traverse_po_uc(节点指针,vector容器):Traverse的内置非递归后序
Traverse_bfs(节点指针,vector容器):Traverse的内置广搜
Traverse(vector容器,模式):以(0先序,1中序,2后序)遍历树,保存到容器,外壳
write(模式):将以(0~2递归前中后序,3~5非递归前中后序,6层序)遍历树的结果输出
*/
纪念我逝去的n个小时的更多相关文章
- luogu_1155: 双栈排序
洛谷1155:双栈排序 题意描述: 给定一个长度为\(n\)的序列\((n\leq 1000)\),两个初始为空的栈,问是否能借助以下四种操作将序列排为升序. \(1:\)如果序列不为空,将第一个元素 ...
- centos7靶机获取不到ip
尝试了好多方法都获取不到靶机ip: 1.首先检查网络链接是否正常 2.重启网卡 /etc/init.d/network restart 3.修改网卡ONBOOT=yes vi /etc/syscon ...
- 如何在joomla上展示word,pdf,xlsx,ppt
去年用slideshare,非常好用,只要在joomla上装上插件,就能直接把slideshare上的文件弄到网站上了,但是前几天突然发现slideshare登不进去了,而<embed>下 ...
- Putnam竞赛一道题及中科大自主招生试题的联系
Putnam试题 For any positive integer n let denote the closest integer to $\sqrt{n}$,Evaluate $$\sum_{n= ...
- Codeforces 1063F - String Journey(后缀数组+线段树+dp)
Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...
- Android开发学习之路-二维码学习
这个月装逼有点少了,为什么呢,因为去考软件射鸡师了,快到儿童节了,赶紧写篇博纪念一下逝去的青春,唔,请忽略这句话. 二维码其实有很多种,但是我们常见的微信使用的是一种叫做QRCode的二维码,像下面这 ...
- 《VIM-Adventures攻略》 LEVEL 1-3
此文已转至http://cn.abnerchou.me/2014/03/04/e40e2146/ 上期有人提到此游戏烂尾.其实没有啦,作者是位"贪财"的主,不付费不给玩剩下的章节. ...
- GIS前端将选中的图形输出为Shapfile文件
老师让我实现如题的功能,我对着ArcGIS js api找了半天,没有发现该方法接口,找了很多资料,前后问了三个前辈. 第一个前辈说用GP服务,我在ArcMap的工具箱里找到convert to la ...
- .Net小白的大学四年,内含面经
大家好 我是码农阿宇,和博客园的广大兄弟一样,我们都喜欢.Net,但是你们是985/211,而我江西一所普通得不能再普通的二本大学---九江学院,大四毕业在即,英语四级未过(为什么强调这一点?见文末- ...
随机推荐
- 2021.07.02 UVa1197 多路归并模板
2021.07.02 UVa1197 多路归并模板 UVA11997 K Smallest Sums - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 分析: 题解 UVA11997 ...
- windows批处理执行图片爬取脚本
背景 由于测试时需要上传一些图片,而自己保存的图片很少. 为了让测试数据看起来不那么重复,所以网上找了一个爬虫脚本,以下是源码: 1 import requests 2 import os 3 4 c ...
- ElasticSearch7.3学习(二十)----采用restful风格查询详解
1.Query DSL入门 1.1 DSL DSL:Domain Specified Language,特定领域的语言.es特有的搜索语言,可在请求体中携带搜索条件,功能强大. 查询全部 GET /b ...
- Quantexa CDI(场景决策智能)Syneo平台介绍
Quantexa 大数据服务提供商, 使用实体解析, 关系分析和人工智能技术帮助客户进行数据处理和预防金融犯罪. 企业概览 2016年成立, 当前规模500人 服务特色是场景决策智能CDI(conte ...
- golang md5加密和python md5加密比较
python md5加密和golang md5加密各有不同,记录于此做备忘 Python 方法 md5 import base64 import hashlib def get_md5_data(bo ...
- B+树能存多少数据?
B+树能存多少数据? 图 MySQL B+树示意图 InnoDB页的大小默认是16KB: 假设一条记录大小为1KB,则一个数据页中可以存16条数据(忽略页中的其他数据结构) 假设主键为int,又指针大 ...
- Android8.0 后台服务保活的一种思路
原文地址:Android8.0 后台服务保活的一种思路 | Stars-One的杂货小窝 项目中有个MQ服务,需要一直连着,接收到消息会发送语音,且手机要在锁屏也要实现此功能 目前是使用广播机制实现, ...
- Java学习笔记-基础语法Ⅷ-泛型、Map
泛型 泛型本质上是参数化类型,也就是说所操作的数据类型被指定为一个参数,即将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类.方法和接口中,分别为泛型类.泛型方法 ...
- 【Java面试】Zookeeper中的Watch机制的原理?
一个工作了7年的粉丝,遇到了一个Zookeeper的问题. 因为接触过Zookeeper这个技术,不知道该怎么回答. 我说一个工作了7年的程序员,没有接触过主流技术,这不正常. 于是我问了他工资以后, ...
- .Net 在容器中操作宿主机
方案描述 在 docker 容器中想操作宿主机,一般会使用 ssh 的方式,然后 .Net 通过执行远程 ssh 指令来操作宿主机.本文将使用 交互式 .Net 容器版 中提供的镜像演示 .Net 在 ...