纪念我逝去的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个小时的更多相关文章

  1. luogu_1155: 双栈排序

    洛谷1155:双栈排序 题意描述: 给定一个长度为\(n\)的序列\((n\leq 1000)\),两个初始为空的栈,问是否能借助以下四种操作将序列排为升序. \(1:\)如果序列不为空,将第一个元素 ...

  2. centos7靶机获取不到ip

    尝试了好多方法都获取不到靶机ip: 1.首先检查网络链接是否正常 2.重启网卡  /etc/init.d/network restart 3.修改网卡ONBOOT=yes vi /etc/syscon ...

  3. 如何在joomla上展示word,pdf,xlsx,ppt

    去年用slideshare,非常好用,只要在joomla上装上插件,就能直接把slideshare上的文件弄到网站上了,但是前几天突然发现slideshare登不进去了,而<embed>下 ...

  4. Putnam竞赛一道题及中科大自主招生试题的联系

    Putnam试题 For any positive integer n let denote the closest integer to $\sqrt{n}$,Evaluate $$\sum_{n= ...

  5. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  6. Android开发学习之路-二维码学习

    这个月装逼有点少了,为什么呢,因为去考软件射鸡师了,快到儿童节了,赶紧写篇博纪念一下逝去的青春,唔,请忽略这句话. 二维码其实有很多种,但是我们常见的微信使用的是一种叫做QRCode的二维码,像下面这 ...

  7. 《VIM-Adventures攻略》 LEVEL 1-3

    此文已转至http://cn.abnerchou.me/2014/03/04/e40e2146/ 上期有人提到此游戏烂尾.其实没有啦,作者是位"贪财"的主,不付费不给玩剩下的章节. ...

  8. GIS前端将选中的图形输出为Shapfile文件

    老师让我实现如题的功能,我对着ArcGIS js api找了半天,没有发现该方法接口,找了很多资料,前后问了三个前辈. 第一个前辈说用GP服务,我在ArcMap的工具箱里找到convert to la ...

  9. .Net小白的大学四年,内含面经

    大家好 我是码农阿宇,和博客园的广大兄弟一样,我们都喜欢.Net,但是你们是985/211,而我江西一所普通得不能再普通的二本大学---九江学院,大四毕业在即,英语四级未过(为什么强调这一点?见文末- ...

随机推荐

  1. 2021.07.02 UVa1197 多路归并模板

    2021.07.02 UVa1197 多路归并模板 UVA11997 K Smallest Sums - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 分析: 题解 UVA11997 ...

  2. windows批处理执行图片爬取脚本

    背景 由于测试时需要上传一些图片,而自己保存的图片很少. 为了让测试数据看起来不那么重复,所以网上找了一个爬虫脚本,以下是源码: 1 import requests 2 import os 3 4 c ...

  3. ElasticSearch7.3学习(二十)----采用restful风格查询详解

    1.Query DSL入门 1.1 DSL DSL:Domain Specified Language,特定领域的语言.es特有的搜索语言,可在请求体中携带搜索条件,功能强大. 查询全部 GET /b ...

  4. Quantexa CDI(场景决策智能)Syneo平台介绍

    Quantexa 大数据服务提供商, 使用实体解析, 关系分析和人工智能技术帮助客户进行数据处理和预防金融犯罪. 企业概览 2016年成立, 当前规模500人 服务特色是场景决策智能CDI(conte ...

  5. golang md5加密和python md5加密比较

    python md5加密和golang md5加密各有不同,记录于此做备忘 Python 方法 md5 import base64 import hashlib def get_md5_data(bo ...

  6. B+树能存多少数据?

    B+树能存多少数据? 图 MySQL B+树示意图 InnoDB页的大小默认是16KB: 假设一条记录大小为1KB,则一个数据页中可以存16条数据(忽略页中的其他数据结构) 假设主键为int,又指针大 ...

  7. Android8.0 后台服务保活的一种思路

    原文地址:Android8.0 后台服务保活的一种思路 | Stars-One的杂货小窝 项目中有个MQ服务,需要一直连着,接收到消息会发送语音,且手机要在锁屏也要实现此功能 目前是使用广播机制实现, ...

  8. Java学习笔记-基础语法Ⅷ-泛型、Map

    泛型 泛型本质上是参数化类型,也就是说所操作的数据类型被指定为一个参数,即将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类.方法和接口中,分别为泛型类.泛型方法 ...

  9. 【Java面试】Zookeeper中的Watch机制的原理?

    一个工作了7年的粉丝,遇到了一个Zookeeper的问题. 因为接触过Zookeeper这个技术,不知道该怎么回答. 我说一个工作了7年的程序员,没有接触过主流技术,这不正常. 于是我问了他工资以后, ...

  10. .Net 在容器中操作宿主机

    方案描述 在 docker 容器中想操作宿主机,一般会使用 ssh 的方式,然后 .Net 通过执行远程 ssh 指令来操作宿主机.本文将使用 交互式 .Net 容器版 中提供的镜像演示 .Net 在 ...