纪念我逝去的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. 新的 css 子选择器

    1. html 结构 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  2. Jquery_效果-隐藏显示、淡入淡出、滑动面板、简单的动画队列

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="U ...

  3. 项目开发字符串模型strstr_while

    #define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <std ...

  4. UML 类之间的关系

    统一建模语言(Unified Modeling Language,UML) 作用:对软件系统进行说明 如果说软件系统是一本小说的话,那么 UML 就是将小说动漫化. 也许你看过这本小说,但是时间一长, ...

  5. 利用撒旦搜索引擎查询ip个数,批量下载ip

    利用撒旦搜索引擎查询ip个数,批量下载ip,使用语言python3.x 批量测试时,为了方便直接撸下ip,所以用python写了个GUI撒旦利用工具,写的不是很好,但能用,最下面有下载. from t ...

  6. RocketMq 完整部署

    目录 RocketMq 部署 环境 物理机部署 自定义日志目录 自定义参数和数据存放位置 服务启动 启动name server 启动broker 关停服务 尝试发送消息 常见报错 部署 rockerm ...

  7. strlen获取字符数组为什么是255

    为什么是255呢? strlen函数的规则是,读取到0则判断字符串结束. char为1字节,只有8位. 所以...... -1就是 1111 1111, -2就是 1111 1110, 直到-128: ...

  8. linux篇-linux面试题汇总

    Linux经典面试题,看看你会几题? 1. 在Linux系统中,以 文件 方式访问设备 . 2. Linux内核引导时,从文件 /etc/fstab 中读取要加载的文件系统. 3. Linux文件系统 ...

  9. ASP.NET MVC 处理管线模型

    MVC管道整体处理模型 1.在ASP.NET MVC处理管线中的第一站就是路由模块.当请求到达路由模块后,MVC框架就会根据Route Table中配置的路由模板来匹配当前请求以获得对应的contro ...

  10. 降维、特征提取与流形学习--非负矩阵分解(NMF)

    非负矩阵分解(NMF)是一种无监督学习算法,目的在于提取有用的特征(可以识别出组合成数据的原始分量),也可以用于降维,通常不用于对数据进行重建或者编码. NMF将每个数据点写成一些分量的加权求和(与P ...